有没有办法用C#编写二进制文字,例如用0x前缀十六进制?0b不起作用。
如果没有,什么是简单的方法?某种字符串转换?
有没有办法用C#编写二进制文字,例如用0x前缀十六进制?0b不起作用。
如果没有,什么是简单的方法?某种字符串转换?
Answers:
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
}
恐怕只能是整数和十六进制(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使用十六进制文字。如果您经常使用二进制数来解决这个问题,那么花十六进制数是值得的。
如果您需要在源代码中查看二进制数字,建议您像上面一样添加带有二进制文字的注释。
您始终可以创建准文字,即包含您所追求的值的常量:
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位二进制文件,我使用它来创建一个静态类,并将其放入剪贴板。至少是静态的,但仍然...我在很多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中实现。但是,Microsoft在2016年3月30日宣布了新版本的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
,如果主机计算机的字节序不低,则可以使用该字段进行测试(并反转缓冲区)。
尽管字符串解析解决方案是最受欢迎的解决方案,但我不喜欢它,因为在某些情况下解析字符串可能会大大降低性能。
当需要一种位域或二进制掩码时,我宁愿这样写
长位掩码= 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)