Используйте константы и дайте им собственные имена, тогда тот факт, что вы должны записать их в десятичном виде, не должен иметь значения. Лично я хотел бы читать, if (a == MaskForModemIOEnabled)а неif (a == 0b100101)
Оба являются очень хорошим советом, за исключением случаев определения указанных битовых полей, где эти определения именованных констант легче читать и записывать с помощью двоичного литерала. [Flags] enum Количество {None = 0, One = 1, Some = 0b10, Most = 0b100, All = 0b111}
Это помогает помнить, что двоичные литералы C # имеют порядок байтов, но в x86 целые числа имеют порядок байтов, поэтому Int16 = 0b0010_0110_0000_0011они будут храниться как { 0b0000_0011, 0b0010_0110 }запутанные.
Дай
1
@Dai ничем не отличается от шестнадцатеричных литералов. Другими словами, все константы с прямым порядком байтов, но хранятся с прямым порядком байтов в Intel / AMD и большинстве ARM. 0xDEADBEEFбудет храниться как0xEF 0xBE 0xAD 0xDE
Коул Джонсон
170
Обновить
В C # 7.0 теперь есть двоичные литералы, и это здорово.
Поскольку тема, похоже, превратилась в объявление значений битовых флагов в перечислениях, я подумал, что стоило бы указать на полезную уловку для такого рода вещей. Оператор сдвига влево ( <<) позволит вам немного подтолкнуть к определенной двоичной позиции. Объедините это с возможностью объявления значений перечисления в терминах других значений в том же классе, и у вас будет очень легкий для чтения декларативный синтаксис для перечислений битовых флагов.
@ColeJohnson: Многие разработчики предпочитают это. Я не так хорош в преобразовании гексагона в моей голове, как некоторые разработчики, и иногда лучше всего удовлетворить наименьший общий знаменатель.
StriplingWarrior
2
Я думаю, что это наиболее эффективный способ, поскольку перечисления строятся как константы. С необязательным атрибутом [Flags] они могут использоваться в побитовых операциях (не связанных непосредственно с вопросом, но особенно полезных при описании двоичных литералов). Другой интересной возможностью является принудительное использование типа enum как встроенного (в этом примере добавьте ': byte' после 'Days'); см. встроенные типы в bit.ly/MKv42E
caligari
Это на самом деле очень легко прочитать, хотя объявление флага 0 в Enum - довольно плохая практика
MikeT
5
@MikeT: Можете ли вы уточнить (или предоставить ссылку, которая развивает) эту последнюю мысль? Я часто объявляю перечисления, которые начинаются с «1», потому что я хочу иметь возможность обнаруживать и быстро сбой, когда значение просто никогда не инициализируется. Но в некоторых ситуациях значение по умолчанию действительно имеет смысл, и я думаю, что не было бы ничего плохого в добавлении имени для этого значения.
StriplingWarrior
3
@MikeT От ca1008 : «Если перечисление, к которому применен атрибут FlagsAttribute, определяет элемент с нулевым значением, его имя должно быть« Нет », чтобы указать, что в перечислении не было задано никаких значений». Поэтому совершенно правильно добавить его в качестве значения по умолчанию, если оно называется «Нет». В целом, мне кажется, что значение в инициализированном по умолчанию поле действительно имеет имя для отображения.
Nyerguds
115
Боюсь, только целое и шестнадцатеричное напрямую (ECMA 334v4):
9.4.4.2 Целочисленные литералы Целочисленные литералы используются для записи значений типов int, uint, long и ulong. Целочисленные литералы имеют две возможные формы: десятичная и шестнадцатеричная.
В качестве обновления к этому ответу, с новейшей современной информацией (июль 2014 года); C # 6.0 вводит двоичные литералы. Смотрите мой обновленный ответ wayyyyyy внизу ...
BTownTKD
1
@BTownTKD ваш ответ на самом деле вверху :), так как это принятый ответ.
RBT
25
В дополнение к ответу @ StriplingWarrior о битовых флагах в перечислениях, есть простое соглашение, которое вы можете использовать в шестнадцатеричном формате для подсчета вверх через битовые сдвиги. Используйте последовательность 1-2-4-8, переместите один столбец влево и повторите.
Сканируйте вниз, начиная с правой колонки, и обратите внимание на схему 1-2-4-8 (смещение) 1-2-4-8 (смещение) ...
Чтобы ответить на первоначальный вопрос, я подкрепляю предложение @ Sahuagin использовать шестнадцатеричные литералы. Если вы работаете с двоичными числами достаточно часто, чтобы это вызывало беспокойство, стоит потратить время на знакомство с шестнадцатеричным.
Если вам нужно увидеть двоичные числа в исходном коде, я предлагаю добавить комментарии с двоичными литералами, как у меня выше.
Если вы используете их часто, вы можете обернуть их в статический класс для повторного использования.
Однако, немного не по теме, если у вас есть какая-либо семантика, связанная с битами (известная во время компиляции), я бы предложил вместо этого использовать Enum:
enumFlags{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
Функция двоичного литерала не была реализована в C # 6.0 и Visual Studio 2015. Но 30 марта 2016 года Microsoft анонсировала новую версию Visual Studio '15' Preview, в которой мы можем использовать двоичные литералы.
Мы можем использовать один или несколько символов подчеркивания (_) для разделителей цифр. поэтому фрагмент кода будет выглядеть примерно так:
int x =0b10___10_0__________________00;//binary value of 80intSeventyFive=0B100_________1011;//binary value of 75WriteLine($" {x} \n {SeventyFive}");
и мы можем использовать любой из 0b и 0B, как показано в приведенном выше фрагменте кода.
если вы не хотите использовать разделитель цифр, вы можете использовать его без разделителя цифр, как показано ниже: фрагмент кода
int x =0b1010000;//binary value of 80intSeventyFive=0B1001011;//binary value of 75WriteLine($" {x} \n {SeventyFive}");
BitConverter становится немного сложнее, потому что это машинный порядок; а на вашем стандартном Intel это означает little-endian. Большинству людей трудно читать буквально-порядковые литералы ...
Марк Гравелл
1
Ой, теперь я помню, почему я всегда знал, но никогда не использовал BitConverter ...
Майкл Стум
4
BitConverter имеет поле BitConverter.IsLittleEndian, которое вы можете использовать для проверки (и реверсирования буфера), если на хост-машине не существует порядка байтов.
лисица
1
Хотя решение для разбора строк является наиболее популярным, оно мне не нравится, потому что в некоторых ситуациях разбор строк может сильно повлиять на производительность.
Когда нужна разновидность битового поля или бинарной маски, я бы предпочел написать
В принципе, я думаю, что ответ НЕТ, простого пути нет. Используйте десятичные или шестнадцатеричные константы - они просты и понятны. Ответ @RoyTinkers тоже хорош - используйте комментарий.
int someHexFlag =0x010;// 000000010000int someDecFlag =8;// 000000001000
Другие ответы здесь представляют несколько полезных рабочих раундов, но я думаю, что они не лучше, чем простой ответ. Разработчики языка C #, вероятно, сочли префикс '0b' ненужным. HEX легко преобразовать в двоичный код, и большинству программистов все равно придется знать DEC-эквиваленты 0-8.
Также при проверке значений в отладчике они будут отображаться как HEX или DEC.
if (a == MaskForModemIOEnabled)
а неif (a == 0b100101)
Ответы:
C # 7.0 поддерживает двоичные литералы (и необязательные разделители цифр через символы подчеркивания).
Пример:
Вы также можете найти больше информации на странице Roslyn GitHub .
источник
Int16 = 0b0010_0110_0000_0011
они будут храниться как{ 0b0000_0011, 0b0010_0110 }
запутанные.0xDEADBEEF
будет храниться как0xEF 0xBE 0xAD 0xDE
Обновить
В C # 7.0 теперь есть двоичные литералы, и это здорово.
Оригинальный пост
Поскольку тема, похоже, превратилась в объявление значений битовых флагов в перечислениях, я подумал, что стоило бы указать на полезную уловку для такого рода вещей. Оператор сдвига влево (
<<
) позволит вам немного подтолкнуть к определенной двоичной позиции. Объедините это с возможностью объявления значений перечисления в терминах других значений в том же классе, и у вас будет очень легкий для чтения декларативный синтаксис для перечислений битовых флагов.источник
Боюсь, только целое и шестнадцатеричное напрямую (ECMA 334v4):
Для разбора вы можете использовать:
источник
В дополнение к ответу @ StriplingWarrior о битовых флагах в перечислениях, есть простое соглашение, которое вы можете использовать в шестнадцатеричном формате для подсчета вверх через битовые сдвиги. Используйте последовательность 1-2-4-8, переместите один столбец влево и повторите.
Сканируйте вниз, начиная с правой колонки, и обратите внимание на схему 1-2-4-8 (смещение) 1-2-4-8 (смещение) ...
Чтобы ответить на первоначальный вопрос, я подкрепляю предложение @ Sahuagin использовать шестнадцатеричные литералы. Если вы работаете с двоичными числами достаточно часто, чтобы это вызывало беспокойство, стоит потратить время на знакомство с шестнадцатеричным.
Если вам нужно увидеть двоичные числа в исходном коде, я предлагаю добавить комментарии с двоичными литералами, как у меня выше.
источник
Вы всегда можете создать квази-литералы, константы, которые содержат значение, которое вы ищете:
Если вы используете их часто, вы можете обернуть их в статический класс для повторного использования.
Однако, немного не по теме, если у вас есть какая-либо семантика, связанная с битами (известная во время компиляции), я бы предложил вместо этого использовать Enum:
источник
Если вы посмотрите на статус реализации языковой функции .NET Compiler Platform («Roslyn»), вы можете ясно увидеть, что в C # 6.0 это запланированная функция, поэтому в следующем выпуске мы сможем сделать это обычным способом.
источник
Используя это, для 8-битного бинарного файла, я использую это для создания статического класса, и он помещает его в буфер обмена. Затем он вставляется в проект и добавляется в раздел Using, поэтому все, что имеет nb001010, извлекается из таблицы, в хотя бы статично, но все же ... Я использую C # для большого количества графического кодирования PIC и часто использую 0b101010 в Hi-Tech C
Пример из кода
:-) NEAL
источник
Функция двоичного литерала не была реализована в C # 6.0 и Visual Studio 2015. Но 30 марта 2016 года Microsoft анонсировала новую версию Visual Studio '15' Preview, в которой мы можем использовать двоичные литералы.
Мы можем использовать один или несколько символов подчеркивания (_) для разделителей цифр. поэтому фрагмент кода будет выглядеть примерно так:
и мы можем использовать любой из 0b и 0B, как показано в приведенном выше фрагменте кода.
если вы не хотите использовать разделитель цифр, вы можете использовать его без разделителя цифр, как показано ниже: фрагмент кода
источник
Хотя невозможно использовать Literal, может быть, BitConverter также может быть решением?
источник
BitConverter.IsLittleEndian
, которое вы можете использовать для проверки (и реверсирования буфера), если на хост-машине не существует порядка байтов.Хотя решение для разбора строк является наиболее популярным, оно мне не нравится, потому что в некоторых ситуациях разбор строк может сильно повлиять на производительность.
Когда нужна разновидность битового поля или бинарной маски, я бы предпочел написать
И позже
Или
Где находится класс BitField
источник
Вы можете использовать
0b000001
начиная с Visual Studio 2017 (C # 7.0)источник
В принципе, я думаю, что ответ НЕТ, простого пути нет. Используйте десятичные или шестнадцатеричные константы - они просты и понятны. Ответ @RoyTinkers тоже хорош - используйте комментарий.
Другие ответы здесь представляют несколько полезных рабочих раундов, но я думаю, что они не лучше, чем простой ответ. Разработчики языка C #, вероятно, сочли префикс '0b' ненужным. HEX легко преобразовать в двоичный код, и большинству программистов все равно придется знать DEC-эквиваленты 0-8.
Также при проверке значений в отладчике они будут отображаться как HEX или DEC.
источник