Apakah ada cara untuk menulis literal biner dalam C #, seperti awalan heksadesimal dengan 0x? 0b tidak berfungsi.
Jika tidak, apa cara mudah untuk melakukannya? Semacam konversi string?
Apakah ada cara untuk menulis literal biner dalam C #, seperti awalan heksadesimal dengan 0x? 0b tidak berfungsi.
Jika tidak, apa cara mudah untuk melakukannya? Semacam konversi string?
Jawaban:
C # 7.0 mendukung literal biner (dan pemisah digit opsional melalui karakter garis bawah).
Sebuah contoh:
int myValue = 0b0010_0110_0000_0011;
Anda juga dapat menemukan informasi lebih lanjut di halaman Roslyn GitHub .
Int16 = 0b0010_0110_0000_0011
akan disimpan sebagai { 0b0000_0011, 0b0010_0110 }
- membingungkan.
0xDEADBEEF
akan disimpan sebagai0xEF 0xBE 0xAD 0xDE
C # 7.0 sekarang memiliki literal biner, yang mengagumkan.
[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
}
Karena topik tampaknya telah beralih ke mendeklarasikan nilai bendera berbasis bit di enum, saya pikir akan bermanfaat untuk menunjukkan trik yang berguna untuk hal semacam ini. Operator shift kiri ( <<
) akan memungkinkan Anda untuk mendorong sedikit ke posisi biner tertentu. Gabungkan itu dengan kemampuan untuk mendeklarasikan nilai enum dalam hal nilai lain di kelas yang sama, dan Anda memiliki sintaks deklaratif yang mudah dibaca untuk bit flag enum.
[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
}
Hanya integer dan hex secara langsung, saya takut (ECMA 334v4):
9.4.4.2 Integer literals Integer literals digunakan untuk menulis nilai tipe int, uint, long, dan ulong. Literal integer memiliki dua bentuk yang mungkin: desimal dan heksadesimal.
Untuk menguraikan, Anda dapat menggunakan:
int i = Convert.ToInt32("01101101", 2);
Menambahkan ke jawaban @ StriplingWarrior tentang flag bit di enums, ada konvensi mudah yang dapat Anda gunakan dalam heksadesimal untuk menghitung ke atas melalui perubahan bit. Gunakan urutan 1-2-4-8, pindahkan satu kolom ke kiri, dan ulangi.
[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
}
Memindai dimulai dengan kolom kanan dan perhatikan pola 1-2-4-8 (shift) 1-2-4-8 (shift) ...
Untuk menjawab pertanyaan awal, saya menyarankan saran kedua @ Sahuagin untuk menggunakan heksadesimal literal. Jika Anda cukup sering menggunakan angka biner untuk masalah ini, ada baiknya Anda memanfaatkan heksadesimal.
Jika Anda perlu melihat angka-angka biner dalam kode sumber, saya sarankan menambahkan komentar dengan literal biner seperti yang saya miliki di atas.
Anda selalu dapat membuat kuasi-literal, konstanta yang berisi nilai yang Anda inginkan:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
Jika Anda sering menggunakannya maka Anda dapat membungkusnya dalam kelas statis untuk digunakan kembali.
Namun, sedikit di luar topik, jika Anda memiliki semantik yang terkait dengan bit (dikenal pada waktu kompilasi) saya akan menyarankan menggunakan Enum sebagai gantinya:
enum Flags
{
First = 0,
Second = 1,
Third = 2,
SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
Jika Anda melihat status implementasi fitur bahasa .NET Compiler Platform ("Roslyn"), Anda dapat dengan jelas melihat bahwa di C # 6.0 ini adalah fitur yang direncanakan, jadi pada rilis berikutnya kita dapat melakukannya dengan cara biasa.
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);
Menggunakan ini, untuk biner 8bit, saya menggunakan ini untuk membuat kelas statis dan memasukkannya ke clipboard .. Kemudian itu akan disisipkan ke proyek dan ditambahkan ke bagian Menggunakan, jadi apa pun dengan nb001010 diambil dari tabel, di paling tidak statis, tapi tetap saja ... Saya menggunakan C # untuk banyak pengkodean gambar PIC dan banyak menggunakan 0b101010 di Hi-Tech C
--contoh dari kode outpt--
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
Fitur literal biner tidak diterapkan di C # 6.0 & Visual Studio 2015. tetapi pada 30 Maret 2016 Microsoft mengumumkan versi baru Pratinjau Visual Studio '15' dengan itu kita dapat menggunakan biner literal.
Kita dapat menggunakan satu atau lebih dari satu karakter Garis Bawah (_) untuk pemisah digit. jadi potongan kode akan terlihat seperti:
int x = 0b10___10_0__________________00; //binary value of 80
int SeventyFive = 0B100_________1011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
dan kita dapat menggunakan 0b dan 0B seperti yang ditunjukkan pada cuplikan kode di atas.
jika Anda tidak ingin menggunakan digit separator Anda dapat menggunakannya tanpa digit separator seperti cuplikan kode di bawah ini
int x = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
Meskipun tidak mungkin menggunakan Literal, mungkin BitConverter juga bisa menjadi solusi?
BitConverter.IsLittleEndian
, yang dapat Anda gunakan untuk menguji (dan membalikkan buffer) jika mesin host tidak sedikit endian.
Meskipun solusi penguraian string adalah yang paling populer, saya tidak menyukainya, karena penguraian string dapat menjadi hit kinerja yang hebat dalam beberapa situasi.
Ketika diperlukan semacam bitfield atau topeng biner, saya lebih suka menuliskannya
bitMask panjang = 1011001;
Dan kemudian
int bit5 = BitField.GetBit (bitMask, 5);
Atau
bool flag5 = BitField.GetFlag (bitMask, 5); `
Di mana kelas BitField berada
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;
}
}
Pada dasarnya, saya pikir jawabannya TIDAK, tidak ada cara mudah. Gunakan konstanta desimal atau heksadesimal - mereka sederhana dan jelas. Jawaban @RoyTinkers juga bagus - gunakan komentar.
int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8; // 000000001000
Jawaban yang lain di sini menyajikan beberapa pekerjaan yang bermanfaat - tetapi saya pikir mereka tidak lebih baik daripada jawaban sederhana. Desainer bahasa C # mungkin dianggap awalan '0b' tidak perlu. HEX mudah dikonversi ke biner, dan sebagian besar programmer harus mengetahui padanan DEC dari 0-8.
Juga, ketika memeriksa nilai dalam debugger, mereka akan ditampilkan memiliki HEX atau DEC.
if (a == MaskForModemIOEnabled)
daripadaif (a == 0b100101)