web-dev-qa-db-ja.com

C#バイナリリテラル

16進数の先頭に0xを付けるなど、C#でバイナリリテラルを記述する方法はありますか? 0bは機能しません。

そうでない場合、それを行う簡単な方法は何ですか?ある種の文字列変換?

170
toxvaerd

C# 7.バイナリリテラル をサポートします(およびアンダースコア文字によるオプションの数字区切り文字)。

例:

int myValue = 0b0010_0110_0000_0011;

Roslyn GitHubページ で詳細を確認することもできます。

123
BTownTKD

更新

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
}
159

整数と16進数のみ直接、私は怖いです(ECMA 334v4):

9.4.4.2整数リテラル整数リテラルは、int、uint、long、ulong型の値を書き込むために使用されます。整数リテラルには、10進数と16進数の2つの形式があります。

解析するには、次を使用できます。

int i = Convert.ToInt32("01101101", 2);
115
Marc Gravell

列挙型のビットフラグに関する@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進数を表示する必要がある場合は、上記のような2進リテラルを使用してコメントを追加することをお勧めします。

25
Roy Tinker

次の値を含む準リテラル、定数をいつでも作成できます。

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);
22
Markus Johnsson

.NET Compiler Platform( "Roslyn")の 言語機能の実装ステータス を見ると、C#6.0でこれが計画されている機能であることが明確にわかります。通常の方法で。

Binary literal status

18
totymedli

バイナリリテラル機能は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}");
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ビットバイナリでは、これを使用して静的クラスを作成し、クリップボードに入れます。その後、プロジェクトに貼り付けられ、Usingセクションに追加されます。少なくとも静的ですが、それでも...私は多くの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, 
}

:-)ニール

3
Neal

リテラルを使用することはできませんが、多分 BitConverter も解決策になりますか?

2
Michael Stum

文字列の解析ソリューションは最も人気がありますが、私はそれが好きではありません。文字列の解析は状況によってはパフォーマンスに大きな影響を与える可能性があるからです。

ある種のビットフィールドまたはバイナリマスクが必要な場合は、次のように記述します。

long bitMask = 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;
    }
}
1

Visual Studio 2017(C#7.0)以降、0b000001を使用できます

1
Xiaoyuvax

基本的に、答えはNOだと思います。簡単な方法はありません。 10進数または16進数の定数を使用します-それらは単純明快です。 @RoyTinkersの回答も良いです-コメントを使用してください。

int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8;     // 000000001000

ここでの他の回答は、いくつかの有用な一回のラウンドを示していますが、単純な答えよりも優れているとは思いません。 C#言語の設計者は、おそらく '0b'プレフィックスは不要だと考えていました。 HEXはバイナリに変換するのが簡単であり、ほとんどのプログラマーは、とにかく0-8に相当するDECを知っている必要があります。

また、デバッガで値を調べると、HEXまたはDECが表示されます。

0
RaoulRubin