16進数の前に0xを付けるなど、C#でバイナリリテラルを書き込む方法はありますか?0bは機能しません。
そうでない場合、それを行う簡単な方法は何ですか?ある種の文字列変換?
16進数の前に0xを付けるなど、C#でバイナリリテラルを書き込む方法はありますか?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
}
整数と16進数のみが直接、恐れています(ECMA 334v4):
9.4.4.2整数リテラル整数リテラルは、int、uint、long、およびulong型の値を書き込むために使用されます。整数リテラルには、10進数と16進数の2つの形式があります。
解析するには、以下を使用できます。
int i = Convert.ToInt32("01101101", 2);
列挙型のビットフラグに関する@StriplingWarriorの回答に加えて、ビットシフトを上方にカウントするために16進数で使用できる簡単な規則があります。シーケンス1-2-4-8を使用して、1列を左に移動し、繰り返します。
[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(シフト)...
元の質問に答えるために、16進リテラルを使用するという@Sahuaginの提案に2番目です。これが問題になるのに十分な頻度で2進数を処理している場合、16進数のこつを取得することは価値があります。
ソースコードで2進数を確認する必要がある場合は、上記のようなバイナリリテラルを含むコメントを追加することをお勧めします。
あなたはいつでもあなたが求めている値を含む準リテラル、定数を作成することができます:
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コンパイラプラットフォーム( "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を持つものはすべて、テーブルから取り出されます最小限の静的ですが、それでも... PICグラフィックコーディングの多くにC#を使用し、Hi-Tech Cでは0b101010を多く使用しています
-コード出力からのサンプル-
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では実装されていませんでしたが、2016年3月30日、Microsoftはバイナリリテラルを使用できるVisual Studio '15' Previewの新バージョンを発表しました。
桁区切り文字には、1つまたは複数のアンダースコア(_)文字を使用できます。したがって、コードスニペットは次のようになります。
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;
}
}
基本的に、答えはノーだと思います。簡単な方法はありません。10進数または16進数の定数を使用してください-それらは単純で明確です。@RoyTinkersの回答も良いです-コメントを使用してください。
int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8; // 000000001000
ここでの他の回答はいくつかの有用な作業(ラウンド)を示していますが、単純な回答よりも優れているとは思いません。C#言語の設計者は、おそらく '0b'プレフィックスは不要だと考えていました。HEXはバイナリに簡単に変換でき、ほとんどのプログラマーはDECで0〜8に相当するものを知っている必要があります。
また、デバッガで値を調べるとき、それらはHEXまたはDECで表示されます。
if (a == MaskForModemIOEnabled)
ではなくif (a == 0b100101)