Есть ли способ написать двоичные литералы в C #, например, префикс шестнадцатеричный с 0x? 0b не работает.
Если нет, то какой простой способ сделать это? Какое-то преобразование строк?
Есть ли способ написать двоичные литералы в C #, например, префикс шестнадцатеричный с 0x? 0b не работает.
Если нет, то какой простой способ сделать это? Какое-то преобразование строк?
Ответы:
C # 7.0 поддерживает двоичные литералы (и необязательные разделители цифр через символы подчеркивания).
Пример:
int myValue = 0b0010_0110_0000_0011;
Вы также можете найти больше информации на странице Roslyn GitHub .
Int16 = 0b0010_0110_0000_0011
они будут храниться как { 0b0000_0011, 0b0010_0110 }
запутанные.
0xDEADBEEF
будет храниться как0xEF 0xBE 0xAD 0xDE
В C # 7.0 теперь есть двоичные литералы, и это здорово.
[Flags]
enum Days
{
None = 0,
Sunday = 0b0000001,
Monday = 0b0000010, // 2
Tuesday = 0b0000100, // 4
Wednesday = 0b0001000, // 8
Thursday = 0b0010000, // 16
Friday = 0b0100000, // etc.
Saturday = 0b1000000,
Weekend = Saturday | Sunday,
Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday
}
Поскольку тема, похоже, превратилась в объявление значений битовых флагов в перечислениях, я подумал, что стоило бы указать на полезную уловку для такого рода вещей. Оператор сдвига влево ( <<
) позволит вам немного подтолкнуть к определенной двоичной позиции. Объедините это с возможностью объявления значений перечисления в терминах других значений в том же классе, и у вас будет очень легкий для чтения декларативный синтаксис для перечислений битовых флагов.
[Flags]
enum Days
{
None = 0,
Sunday = 1,
Monday = 1 << 1, // 2
Tuesday = 1 << 2, // 4
Wednesday = 1 << 3, // 8
Thursday = 1 << 4, // 16
Friday = 1 << 5, // etc.
Saturday = 1 << 6,
Weekend = Saturday | Sunday,
Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday
}
Боюсь, только целое и шестнадцатеричное напрямую (ECMA 334v4):
9.4.4.2 Целочисленные литералы Целочисленные литералы используются для записи значений типов int, uint, long и ulong. Целочисленные литералы имеют две возможные формы: десятичная и шестнадцатеричная.
Для разбора вы можете использовать:
int i = Convert.ToInt32("01101101", 2);
В дополнение к ответу @ StriplingWarrior о битовых флагах в перечислениях, есть простое соглашение, которое вы можете использовать в шестнадцатеричном формате для подсчета вверх через битовые сдвиги. Используйте последовательность 1-2-4-8, переместите один столбец влево и повторите.
[Flags]
enum Scenery
{
Trees = 0x001, // 000000000001
Grass = 0x002, // 000000000010
Flowers = 0x004, // 000000000100
Cactus = 0x008, // 000000001000
Birds = 0x010, // 000000010000
Bushes = 0x020, // 000000100000
Shrubs = 0x040, // 000001000000
Trails = 0x080, // 000010000000
Ferns = 0x100, // 000100000000
Rocks = 0x200, // 001000000000
Animals = 0x400, // 010000000000
Moss = 0x800, // 100000000000
}
Сканируйте вниз, начиная с правой колонки, и обратите внимание на схему 1-2-4-8 (смещение) 1-2-4-8 (смещение) ...
Чтобы ответить на первоначальный вопрос, я подкрепляю предложение @ Sahuagin использовать шестнадцатеричные литералы. Если вы работаете с двоичными числами достаточно часто, чтобы это вызывало беспокойство, стоит потратить время на знакомство с шестнадцатеричным.
Если вам нужно увидеть двоичные числа в исходном коде, я предлагаю добавить комментарии с двоичными литералами, как у меня выше.
Вы всегда можете создать квази-литералы, константы, которые содержат значение, которое вы ищете:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
Если вы используете их часто, вы можете обернуть их в статический класс для повторного использования.
Однако, немного не по теме, если у вас есть какая-либо семантика, связанная с битами (известная во время компиляции), я бы предложил вместо этого использовать Enum:
enum Flags
{
First = 0,
Second = 1,
Third = 2,
SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
Если вы посмотрите на статус реализации языковой функции .NET Compiler Platform («Roslyn»), вы можете ясно увидеть, что в C # 6.0 это запланированная функция, поэтому в следующем выпуске мы сможем сделать это обычным способом.
string sTable="static class BinaryTable\r\n{";
string stemp = "";
for (int i = 0; i < 256; i++)
{
stemp = System.Convert.ToString(i, 2);
while(stemp.Length<8) stemp = "0" + stemp;
sTable += "\tconst char nb" + stemp + "=" + i.ToString() + ";\r\n";
}
sTable += "}";
Clipboard.Clear();
Clipboard.SetText ( sTable);
MessageBox.Show(sTable);
Используя это, для 8-битного бинарного файла, я использую это для создания статического класса, и он помещает его в буфер обмена. Затем он вставляется в проект и добавляется в раздел Using, поэтому все, что имеет nb001010, извлекается из таблицы, в хотя бы статично, но все же ... Я использую C # для большого количества графического кодирования PIC и часто использую 0b101010 в Hi-Tech C
Пример из кода
static class BinaryTable
{ const char nb00000000=0;
const char nb00000001=1;
const char nb00000010=2;
const char nb00000011=3;
const char nb00000100=4;
//etc, etc, etc, etc, etc, etc, etc,
}
:-) NEAL
Функция двоичного литерала не была реализована в C # 6.0 и Visual Studio 2015. Но 30 марта 2016 года Microsoft анонсировала новую версию Visual Studio '15' Preview, в которой мы можем использовать двоичные литералы.
Мы можем использовать один или несколько символов подчеркивания (_) для разделителей цифр. поэтому фрагмент кода будет выглядеть примерно так:
int x = 0b10___10_0__________________00; //binary value of 80
int SeventyFive = 0B100_________1011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
и мы можем использовать любой из 0b и 0B, как показано в приведенном выше фрагменте кода.
если вы не хотите использовать разделитель цифр, вы можете использовать его без разделителя цифр, как показано ниже: фрагмент кода
int x = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
Хотя невозможно использовать Literal, может быть, BitConverter также может быть решением?
BitConverter.IsLittleEndian
, которое вы можете использовать для проверки (и реверсирования буфера), если на хост-машине не существует порядка байтов.
Хотя решение для разбора строк является наиболее популярным, оно мне не нравится, потому что в некоторых ситуациях разбор строк может сильно повлиять на производительность.
Когда нужна разновидность битового поля или бинарной маски, я бы предпочел написать
long bitMask = 1011001;
И позже
int bit5 = BitField.GetBit (bitMask, 5);
Или
bool flag5 = BitField.GetFlag (bitMask, 5); `
Где находится класс BitField
public static class BitField
{
public static int GetBit(int bitField, int index)
{
return (bitField / (int)Math.Pow(10, index)) % 10;
}
public static bool GetFlag(int bitField, int index)
{
return GetBit(bitField, index) == 1;
}
}
В принципе, я думаю, что ответ НЕТ, простого пути нет. Используйте десятичные или шестнадцатеричные константы - они просты и понятны. Ответ @RoyTinkers тоже хорош - используйте комментарий.
int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8; // 000000001000
Другие ответы здесь представляют несколько полезных рабочих раундов, но я думаю, что они не лучше, чем простой ответ. Разработчики языка C #, вероятно, сочли префикс '0b' ненужным. HEX легко преобразовать в двоичный код, и большинству программистов все равно придется знать DEC-эквиваленты 0-8.
Также при проверке значений в отладчике они будут отображаться как HEX или DEC.
if (a == MaskForModemIOEnabled)
а неif (a == 0b100101)