Бинарные литералы С#

Есть ли способ написать бинарные литералы в С#, например, префикс шестнадцатеричного с 0x? 0b не работает.

Если нет, что это простой способ сделать это? Какое-то преобразование строк?

Ответ 1

С# 7.0 поддерживает бинарные литералы (и необязательную цифру разделители через символы подчеркивания).

Пример:

int myValue = 0b0010_0110_0000_0011;

Вы также можете найти дополнительную информацию на странице Roslyn GitHub.

Ответ 2

Поскольку тема, похоже, обратилась к объявлению значений флагов на основе бит в перечислениях, я подумал, что было бы полезно указать на удобную трюк для такого рода вещей. Оператор с левым сдвигом (<<) позволит вам надавить бит на конкретную двоичную позицию. Объедините это с возможностью объявлять значения перечисления в терминах других значений в одном классе, и у вас есть очень простой для чтения декларативный синтаксис для перечислений флагов бит.

[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
}

Ответ 3

Я боюсь только целых и шестнадцатеричных (ECMA 334v4):

9.4.4.2 Целочисленные литералы Целочисленные литералы используются для записи значений типы int, uint, long и ulong. Целочисленные литералы имеют два возможных формы: десятичные и шестнадцатеричные.

Для синтаксического анализа вы можете использовать:

int i = Convert.ToInt32("01101101", 2);

Ответ 4

Добавляя к @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 использовать шестнадцатеричные литералы. Если вы работаете с двоичными числами, достаточно часто для того, чтобы это было проблемой, стоит потратить время на то, чтобы получить шестнадцатеричный вид.

Если вам нужно увидеть двоичные числа в исходном коде, я предлагаю добавить комментарии с бинарными литералами, как у меня выше.

Ответ 5

Вы всегда можете создавать квази-литералы, константы, которые содержат значение, которое вы после:

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);

Ответ 7

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-битного двоичного файла я использую это, чтобы сделать статический класс, и он помещает его в буфер обмена. Затем он вставляется в проект и добавляется в раздел "Использование", поэтому все, что с nb001010 извлекается из стол, по крайней мере статический, но все же... Я использую С# для большого количества графического кодирования 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

Ответ 8

Функция Binary literal не была реализована в С# 6.0 и Visual Studio 2015. но 30 марта 2016 г. Microsoft анонсировала новую версию Visual Studio '15' Preview с тем, что мы можем использовать бинарные литералы.

Мы можем использовать один или несколько символов Underscore (_) для разделителей цифр. поэтому фрагмент кода будет выглядеть примерно так:

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}");

Ответ 9

Пока невозможно использовать Literal, возможно, BitConverter также может быть решением?

Ответ 10

Хотя решение синтаксического анализа является наиболее популярным, мне оно не нравится, потому что синтаксический анализ может привести к большим результатам в некоторых ситуациях.

Если вам нужна какая-то битовая или двоичная маска, я бы предпочел написать ее как

long bitMask = 1011001;

И позже

int бит5 = битField.GetBit(битмаск, 5);

или

bool flag5 = BitField.GetFlag(битмаск, 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;
    }
}

Ответ 11

В принципе, я думаю, что ответ НЕТ, нет простого способа. Используйте десятичные или шестнадцатеричные константы - они просты и понятны. Ответ @RoyTinkers также хорош - используйте комментарий.

int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8;     // 000000001000

Другие ответы здесь представляют несколько полезных работ - раундов, но я думаю, что они не лучше, чем простой ответ. Разработчики языка С#, вероятно, считали префикс "0b" ненужным. HEX легко преобразовать в двоичный файл, и большинство программистов должны знать эквиваленты DEC 0-8 в любом случае.

Кроме того, при проверке значений в отладчике они будут отображаться с использованием HEX или DEC.

Ответ 12

Вы можете использовать 0b000001, поскольку Visual Studio 2017 (С# 7.0)