Gunakan konstanta dan beri mereka nama yang tepat, maka fakta bahwa Anda harus menuliskannya dalam desimal tidak masalah. Secara pribadi saya ingin membaca if (a == MaskForModemIOEnabled)daripadaif (a == 0b100101)
Keduanya saran yang sangat baik, kecuali ketika mendefinisikan bitfields kata, di mana definisi konstan bernama ini dapat lebih mudah dibaca dan ditulis dengan literal biner. [Bendera] enum Kuantitas {Tidak Ada = 0, Satu = 1, Beberapa = 0b10, Paling = 0b100, Semua = 0b111}
Ini membantu untuk mengingat bahwa Binary Literals C # adalah big-endian, tetapi pada x86 integer adalah little-endian, jadi Int16 = 0b0010_0110_0000_0011akan disimpan sebagai { 0b0000_0011, 0b0010_0110 }- membingungkan.
Dai
1
@ Hai itu tidak berbeda dari hex literal. Dengan kata lain, semua konstanta adalah endian besar, tetapi disimpan endian kecil pada Intel / AMD dan sebagian besar ARM. 0xDEADBEEFakan disimpan sebagai0xEF 0xBE 0xAD 0xDE
Cole Johnson
170
Memperbarui
C # 7.0 sekarang memiliki literal biner, yang mengagumkan.
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.
@ColeJohnson: Banyak pengembang lebih suka itu. Saya tidak sebagus mengkonversi hex di kepala saya seperti beberapa pengembang, dan kadang-kadang lebih baik untuk memenuhi penyebut umum terendah.
StriplingWarrior
2
Saya pikir ini adalah cara paling efektif karena enum dibangun sebagai konstanta. Dengan atribut [Bendera] opsional, mereka dapat digunakan dalam operasi bitwise (tidak terkait langsung dengan pertanyaan, tetapi sangat berguna saat menggambarkan literal biner). Kemungkinan menarik lainnya adalah untuk memaksa tipe enum sebagai tipe bawaan (dalam contoh ini, tambahkan ': byte' setelah 'Days'); lihat tipe bawaan
caligari
Itu sebenarnya sangat mudah dibaca, meskipun menyatakan bendera 0 pada Enum adalah praktik yang cukup buruk
MikeT
5
@ MikeT: Dapatkah Anda menguraikan (atau memberikan tautan yang menguraikan) pemikiran terakhir itu? Saya sering menyatakan enum yang dimulai dengan "1" karena saya ingin dapat mendeteksi dan gagal-cepat ketika suatu nilai tidak pernah diinisialisasi. Tetapi ada beberapa situasi di mana nilai default benar-benar masuk akal, dan saya pikir tidak akan ada salahnya dengan menambahkan nama untuk nilai itu.
StriplingWarrior
3
@MikeT Dari ca1008 : "Jika enumerasi yang menerapkan FlagsAttribute mendefinisikan anggota bernilai nol, namanya harus 'Tidak Ada' untuk menunjukkan bahwa tidak ada nilai yang telah ditetapkan dalam enumerasi." Jadi sangat sah untuk menambahkannya sebagai nilai default, jika itu disebut "Tidak Ada". Secara keseluruhan sepertinya lebih bersih bagi saya jika nilai dalam bidang inisialisasi default sebenarnya memiliki nama untuk ditampilkan.
Nyerguds
115
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.
Sebagai pembaruan untuk jawaban ini, dengan informasi modern mutakhir terbaru (Juli, 2014); C # 6.0 memperkenalkan literal biner. Lihat jawaban saya yang diperbarui wayyyyyy di bagian bawah ...
BTownTKD
1
@BTownTKD jawaban Anda sebenarnya ada di atas :) karena itu adalah jawaban yang diterima.
RBT
25
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.
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.
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:
enumFlags{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
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 80intSeventyFive=0B100_________1011;//binary value of 75WriteLine($" {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 80intSeventyFive=0B1001011;//binary value of 75WriteLine($" {x} \n {SeventyFive}");
BitConverter menjadi sedikit rumit karena merupakan mesin-endian; dan pada Intel standar Anda, itu berarti little-endian. Kebanyakan orang mengalami kesulitan membaca literal little-endian ...
Marc Gravell
1
Aduh, sekarang aku ingat mengapa aku selalu sadar tapi tidak pernah menggunakan BitConverter ...
Michael Stum
4
BitConverter memiliki bidang BitConverter.IsLittleEndian, yang dapat Anda gunakan untuk menguji (dan membalikkan buffer) jika mesin host tidak sedikit endian.
foxy
1
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
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;// 000000010000int 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)
Jawaban:
C # 7.0 mendukung literal biner (dan pemisah digit opsional melalui karakter garis bawah).
Sebuah contoh:
Anda juga dapat menemukan informasi lebih lanjut di halaman Roslyn GitHub .
sumber
Int16 = 0b0010_0110_0000_0011
akan disimpan sebagai{ 0b0000_0011, 0b0010_0110 }
- membingungkan.0xDEADBEEF
akan disimpan sebagai0xEF 0xBE 0xAD 0xDE
Memperbarui
C # 7.0 sekarang memiliki literal biner, yang mengagumkan.
Pos Asli
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.sumber
Hanya integer dan hex secara langsung, saya takut (ECMA 334v4):
Untuk menguraikan, Anda dapat menggunakan:
sumber
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.
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.
sumber
Anda selalu dapat membuat kuasi-literal, konstanta yang berisi nilai yang Anda inginkan:
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:
sumber
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.
sumber
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--
:-) NEAL
sumber
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:
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
sumber
Meskipun tidak mungkin menggunakan Literal, mungkin BitConverter juga bisa menjadi solusi?
sumber
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
Dan kemudian
Atau
Di mana kelas BitField berada
sumber
Anda dapat menggunakan
0b000001
sejak Visual Studio 2017 (C # 7.0)sumber
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.
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.
sumber