209

有没有办法在 C# 中编写二进制文字,比如在十六进制前面加上 0x?0b 不起作用。

如果没有,有什么简单的方法可以做到这一点?某种字符串转换?

4

12 回答 12

198

更新

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
}
于 2011-08-16T21:48:17.303 回答
172

C# 7.0支持二进制文字(以及通过下划线字符的可选数字分隔符)。

一个例子:

int myValue = 0b0010_0110_0000_0011;

您还可以在Roslyn GitHub 页面上找到更多信息。

于 2014-05-08T15:37:59.730 回答
117

恐怕只有整数和十六进制(ECMA 334v4):

9.4.4.2 整数文字整数文字用于写入 int、uint、long 和 ulong 类型的值。整数文字有两种可能的形式:十进制和十六进制。

要解析,您可以使用:

int i = Convert.ToInt32("01101101", 2);
于 2009-02-27T13:27:33.567 回答
26

添加到@StriplingWarrior 关于枚举中位标志的答案中,您可以使用一个简单的约定以十六进制形式通过位移位向上计数。使用序列 1-2-4-8,向左移动一列,然后重复。

[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 (shift) 1-2-4-8 (shift) ...


为了回答最初的问题,我赞同@Sahuagin 使用十六进制文字的建议。如果您经常使用二进制数来解决这个问题,那么值得您花时间掌握十六进制的窍门。

如果您需要在源代码中查看二进制数字,我建议您使用上面的二进制文字添加注释。

于 2013-11-18T22:03:47.373 回答
24

您始终可以创建包含您所追求的值的准字面量常量:

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);
于 2010-07-29T11:42:49.917 回答
18

如果您查看 .NET 编译器平台(“Roslyn”)的语言功能实现状态,您可以清楚地看到在 C# 6.0 中这是一个计划中的功能,因此在下一个版本中我们可以按照通常的方式进行。

二进制文字状态

于 2014-04-10T21:24:47.810 回答
3
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 的东西都从表中取出,在最少静态,但仍然...我使用 C# 进行大量 PIC 图形编码,并在 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, 
}

:-) 尼尔

于 2011-11-10T20:19:10.780 回答
3

二进制文字功能未在 C# 6.0 和 Visual Studio 2015 中实现。但在 2016 年 3 月 30 日,微软宣布了新版本的 Visual Studio '15' 预览版,我们可以使用二进制文字。

我们可以使用一个或多个下划线(_)字符作为数字分隔符。所以代码片段看起来像:

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}");
于 2016-04-03T06:43:13.550 回答
2

虽然不可能使用 Literal,但也许BitConverter也可以是一个解决方案?

于 2009-02-27T13:31:56.350 回答
1

尽管字符串解析解决方案是最流行的,但我不喜欢它,因为在某些情况下解析字符串可能会对性能产生很大影响。

当需要一种位域或二进制掩码时,我宁愿这样写

长位掩码 = 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;
    }
}
于 2010-09-23T08:28:34.817 回答
1

您可以0b000001从 Visual Studio 2017 (C# 7.0) 开始使用

于 2017-08-02T06:22:05.057 回答
0

基本上,我认为答案是否定的,没有简单的方法。使用十进制或十六进制常量——它们简单明了。@RoyTinkers 的回答也很好 - 使用评论。

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

这里的其他答案提出了几个有用的工作——一轮,但我认为它们并不比简单的答案更好。C# 语言设计者可能认为不需要“0b”前缀。HEX 很容易转换为二进制,大多数程序员无论如何都必须知道 0-8 的 DEC 等价物。

此外,在调试器中检查值时,它们将显示为 HEX 或 DEC。

于 2014-04-08T22:24:10.990 回答