[c#] Бинарные литералы C #



5 Answers

Обновить

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

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

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




Если вы посмотрите на статус реализации функции языка платформы .NET Compiler Platform («Roslyn»), вы можете ясно видеть, что в C # 6.0 это запланированная функция, поэтому в следующей версии мы можем сделать это обычным способом.




Добавляя к ответу @ 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 (сдвиг) ...

Чтобы ответить на исходный вопрос, я предлагаю второе предложение Сахуагина использовать шестнадцатеричные литералы. Если вы часто работаете с двоичными числами, чтобы это было проблемой, стоит потратить время на то, чтобы получить шестнадцатеричный размер.

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




Функция Binary literal не была реализована в C # 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}");



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

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

long bitMask = 1011001;

И позже

int bit5 = BitField.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;
    }
}



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




Related