有没有类似于在 C# 中使用 0x 前缀表示十六进制的二进制字面量写法?0b 不起作用。
如果没有,那么有什么简单的方法可以实现呢?是某种字符串转换吗?
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
}
01
和1
一样。但是包含这些零可以帮助开发人员可视化地了解二进制位的位置。 - StriplingWarriorint myValue = 0b0010_0110_0000_0011;
Int16 = 0b0010_0110_0000_0011
将被存储为{0b0000_0011, 0b0010_0110}
- 这很令人困惑。 - Dai0xDEADBEEF
将被存储为0xEF 0xBE 0xAD 0xDE
。 - Cole Tobin很遗憾,只能直接使用整数和十六进制(ECMA 334v4):
9.4.4.2 整数字面值 整数字面值用于表示 int、uint、long 和 ulong 类型的值。整数字面值有两种可能的形式:十进制和十六进制。
如果要解析,可以使用以下方法:
int i = Convert.ToInt32("01101101", 2);
在@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(移位)1-2-4-8(移位)...
回答原问题,我支持 @Sahuagin 的建议,使用十六进制字面量。如果你经常使用二进制数,这很值得你去掌握十六进制。
如果你需要在源代码中看到二进制数字,我建议像我上面那样添加带有二进制字面量的注释。
Trees = 0x001,
Grass = 1 << 1,
Flowers = 1 << 2,
Cactus = 1 << 3,
};```
你只需要从0或1开始,然后每个接下来的1(从2开始)都会简单地左移一个递增的操作数。<< 1、<< 2、<< 3、<< 4、<< 5等等。当需要更改大型枚举时,更容易正确编辑。
(编辑:如果有人能帮忙更好地格式化,请务必帮忙)
- Aaron Carter您始终可以创建准字面量,即包含您需要的值的常量:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
如果您经常使用它们,可以将它们包装在一个静态类中以供重用。
但是,有点离题,如果您有与位相关联的语义(在编译时已知),我建议使用枚举:
enum Flags
{
First = 0,
Second = 1,
Third = 2,
SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
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);
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
在C# 6.0和Visual Studio 2015中,并没有实现二进制字面量特性。但是,在2016年3月30日,Microsoft宣布了新版本的Visual Studio '15' Preview,在这个版本中我们可以使用二进制字面量。
我们可以使用一个或多个下划线(_)字符作为数字分隔符。因此,代码片段可能如下所示:
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
,你可以使用它来测试(并反转缓冲区),以判断主机是否为小端字节序。 - foxy虽然字符串解析方案是最流行的,但我不喜欢它,因为在某些情况下解析字符串可能会对性能造成很大的影响。
当需要一种位域或二进制掩码时,我宁愿像这样编写:
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;
}
}
if (a == MaskForModemIOEnabled)
而不是if (a == 0b100101)
。 - Lasse V. Karlsen