Czy istnieje sposób pisania literałów binarnych w języku C #, na przykład przedrostek szesnastkowy z 0x? 0b nie działa.
Jeśli nie, to jak łatwo to zrobić? Jakaś konwersja ciągu?
Czy istnieje sposób pisania literałów binarnych w języku C #, na przykład przedrostek szesnastkowy z 0x? 0b nie działa.
Jeśli nie, to jak łatwo to zrobić? Jakaś konwersja ciągu?
Odpowiedzi:
C # 7.0 obsługuje literały binarne (i opcjonalne separatory cyfr za pomocą znaków podkreślenia).
Przykład:
int myValue = 0b0010_0110_0000_0011;
Możesz również znaleźć więcej informacji na stronie Roslyn GitHub .
Int16 = 0b0010_0110_0000_0011
będą przechowywane jako { 0b0000_0011, 0b0010_0110 }
- mylące.
0xDEADBEEF
będą przechowywane jako0xEF 0xBE 0xAD 0xDE
C # 7.0 ma teraz literały binarne, co jest niesamowite.
[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
}
Ponieważ wydaje się, że temat zwrócił się do deklarowania wartości flag opartych na bitach w wyliczeniach, pomyślałem, że warto wskazać przydatną sztuczkę w tego typu sprawach. Operator shift-left ( <<
) pozwoli ci przesunąć nieco do określonej pozycji binarnej. W połączeniu z możliwością deklarowania wartości wyliczeniowych w odniesieniu do innych wartości w tej samej klasie, masz bardzo łatwą do odczytania deklaratywną składnię wyliczeń flag bitowych.
[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
}
Obawiam się, że tylko liczba całkowita i hex bezpośrednio (ECMA 334v4):
9.4.4.2 Literały całkowite Literały całkowite są używane do zapisywania wartości typów int, uint, long i ulong. Literały całkowite mają dwie możliwe formy: dziesiętną i szesnastkową.
Do parsowania możesz użyć:
int i = Convert.ToInt32("01101101", 2);
Dodając do odpowiedzi @ StriplingWarrior na temat flag bitów w wyliczeniach, istnieje prosta konwencja, której można używać w systemie szesnastkowym do liczenia w górę przez przesunięcia bitów. Użyj sekwencji 1-2-4-8, przesuń jedną kolumnę w lewo i powtórz.
[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
}
Zeskanuj w dół, zaczynając od prawej kolumny i zauważ wzór 1-2-4-8 (shift) 1-2-4-8 (shift) ...
Aby odpowiedzieć na pierwotne pytanie, popieram sugestię @ Sahuagin, by używać literałów szesnastkowych. Jeśli pracujesz z liczbami binarnymi wystarczająco często, aby było to niepokojące, warto poświęcić chwilę na sprawdzenie szesnastkowego.
Jeśli chcesz zobaczyć liczby binarne w kodzie źródłowym, sugeruję dodawanie komentarzy z literałami binarnymi, tak jak mam powyżej.
Zawsze możesz tworzyć quasi-literały, stałe zawierające szukaną wartość:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
Jeśli często ich używasz, możesz owinąć je w klasę statyczną do ponownego użycia.
Jednak nieco nie na temat, jeśli masz jakieś semantyki związane z bitami (znane w czasie kompilacji), sugerowałbym użycie zamiast tego Enum:
enum Flags
{
First = 0,
Second = 1,
Third = 2,
SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
Jeśli spojrzysz na status implementacji funkcji językowych platformy kompilatora .NET („Roslyn”), możesz wyraźnie zauważyć, że w C # 6.0 jest to funkcja planowana, więc w następnej wersji możemy to zrobić w zwykły sposób.
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);
Używając tego, dla 8-bitowego pliku binarnego, używam tego, aby utworzyć klasę statyczną i umieszcza go w schowku. Następnie jest wklejany do projektu i dodawany do sekcji Używanie, więc wszystko z nb001010 jest usuwane ze stołu, na najmniej statyczny, ale wciąż ... Używam C # do kodowania grafiki PIC i dużo 0b101010 w Hi-Tech C
- próbka z opisu kodu--
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
Funkcja dosłowności binarnej nie została zaimplementowana w C # 6.0 i Visual Studio 2015. ale 30 marca 2016 r. Microsoft ogłosił nową wersję Visual Studio „15” Preview, w której możemy używać literałów binarnych.
Możemy użyć jednego lub więcej niż jednego znaku podkreślenia (_) dla separatorów cyfr. więc fragment kodu wyglądałby mniej więcej tak:
int x = 0b10___10_0__________________00; //binary value of 80
int SeventyFive = 0B100_________1011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
i możemy użyć wartości 0b i 0B, jak pokazano w powyższym fragmencie kodu.
jeśli nie chcesz używać separatora cyfr, możesz go używać bez separatora cyfr, jak poniżej fragmentu kodu
int x = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
Chociaż nie jest to możliwe przy użyciu dosłowności , może BitConverter może być również rozwiązaniem?
BitConverter.IsLittleEndian
, którego możesz użyć do przetestowania (i odwrócenia bufora), jeśli komputer-host nie jest małym endianem.
Chociaż parsowanie łańcucha jest najpopularniejsze, nie podoba mi się to, ponieważ parsowanie łańcucha może być świetnym hitem wydajności w niektórych sytuacjach.
Gdy potrzebuję czegoś w rodzaju pola bitowego lub maski binarnej, wolałbym napisać to tak
długa maska bitowa = 1011001;
I później
int bit5 = BitField.GetBit (bitMask, 5);
Lub
bool flag5 = BitField.GetFlag (bitMask, 5); `
Gdzie jest klasa 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;
}
}
Zasadniczo myślę, że odpowiedź brzmi NIE, nie ma łatwego sposobu. Używaj stałych dziesiętnych lub szesnastkowych - są one proste i jasne. Odpowiedź @RoyTinkers jest również dobra - użyj komentarza.
int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8; // 000000001000
Pozostałe odpowiedzi tutaj przedstawiają kilka przydatnych rund - ale myślę, że nie są lepsze niż prosta odpowiedź. Projektanci języka C # prawdopodobnie uznali za niepotrzebny prefiks „0b”. HEX można łatwo przekonwertować na binarny, a większość programistów będzie musiała znać odpowiedniki DEC 0–8.
Ponadto, podczas sprawdzania wartości w debuggerze, będą wyświetlane jako HEX lub DEC.
if (a == MaskForModemIOEnabled)
raczej czytać niżif (a == 0b100101)