Чи є спосіб записати двійкові літерали на 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 (зміна) ...
Щоб відповісти на початкове запитання, я друге пропозицію @ Сахуагіна використовувати шістнадцяткові літерали. Якщо ви працюєте з двійковими числами досить часто, щоб це викликало занепокоєння, варто витратити час на отримання шестинадцяткової повіси.
Якщо вам потрібно побачити двійкові числа у вихідному коді, я пропоную додати коментарі з бінарними буквами, як у мене вище.
Ви завжди можете створювати квазілітерали, константи яких містять значення, яке ви шукаєте:
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-бітового двійкового я використовую це для створення статичного класу, і він кладе його в буфер обміну. Потім він вставляється в проект і додається в розділ Використання, тому все з 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,
}
:-) НЕАЛЬНО
Функція бінарного літералу не була реалізована в 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
, яке ви можете використовувати для тестування (і повернення буфера), якщо хост-машина не мало ендіан.
Хоча рішення для розбору рядків є найпопулярнішим, мені це не подобається, оскільки синтаксичний розбір може бути чудовим результатом у деяких ситуаціях.
Коли потрібна якась бітфілд або бінарна маска, я б краще написав це як
довга бітова маска = 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)