C# 二进制文字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/594720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# binary literals
提问by toxvaerd
Is there a way to write binary literals in C#, like prefixing hexadecimal with 0x? 0b doesn't work.
有没有办法在 C# 中编写二进制文字,比如在十六进制前面加上 0x?0b 不起作用。
If not, what is an easy way to do it? Some kind of string conversion?
如果没有,有什么简单的方法可以做到?某种字符串转换?
采纳答案by BTownTKD
C# 7.0supports binary literals(and optional digit separators via underscore characters).
C# 7.0支持二进制文字(以及通过下划线字符的可选数字分隔符)。
An example:
一个例子:
int myValue = 0b0010_0110_0000_0011;
You can also find more information on the Roslyn GitHub page.
您还可以在Roslyn GitHub 页面上找到更多信息。
回答by Marc Gravell
Only integer and hex directly, I'm afraid (ECMA 334v4):
恐怕只有整数和十六进制直接(ECMA 334v4):
9.4.4.2 Integer literalsInteger literals are used to write values of types int, uint, long, and ulong. Integer literals have two possible forms: decimal and hexadecimal.
9.4.4.2 整数文字整数文字用于写入 int、uint、long 和 ulong 类型的值。整数文字有两种可能的形式:十进制和十六进制。
To parse, you can use:
要解析,您可以使用:
int i = Convert.ToInt32("01101101", 2);
回答by Michael Stum
While not possible using a Literal, maybe a BitConvertercan also be a solution?
虽然不可能使用文字,也许BitConverter也可以是一个解决方案?
回答by Markus Johnsson
You can always create quasi-literals, constants which contain the value you are after:
您始终可以创建包含您所追求的值的准文字常量:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
If you use them often then you can wrap them in a static class for re-use.
如果您经常使用它们,那么您可以将它们包装在一个静态类中以供重复使用。
However, slightliy off-topic, if you have any semantics associated with the bits (known at compile time) I would suggest using an Enum instead:
但是,稍微偏离主题,如果您有任何与位相关的语义(在编译时已知),我建议改用 Enum:
enum Flags
{
First = 0,
Second = 1,
Third = 2,
SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
回答by Dmitry Tashkinov
Though the string parsing solution is the most popular, I don't like it, because parsing string can be a great performance hit in some situations.
尽管字符串解析解决方案是最流行的,但我不喜欢它,因为在某些情况下解析字符串可能会极大地影响性能。
When there is needed a kind of a bitfield or binary mask, I'd rather write it like
当需要一种位域或二进制掩码时,我宁愿这样写
long bitMask = 1011001;
长位掩码 = 1011001;
And later
然后
int bit5 = BitField.GetBit(bitMask, 5);
int bit5 = BitField.GetBit(bitMask, 5);
Or
或者
bool flag5 = BitField.GetFlag(bitMask, 5);`
bool flag5 = BitField.GetFlag(bitMask, 5);`
Where BitField class is
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;
}
}
回答by StriplingWarrior
Update
更新
C# 7.0 now has binary literals, which is awesome.
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
}
Original Post
原帖
Since the topic seems to have turned to declaring bit-based flag values in enums, I thought it would be worth pointing out a handy trick for this sort of thing. The left-shift operator (<<
) will allow you to push a bit to a specific binary position. Combine that with the ability to declare enum values in terms of other values in the same class, and you have a very easy-to-read declarative syntax for bit flag enums.
由于该主题似乎已转向在枚举中声明基于位的标志值,因此我认为值得为此类事情指出一个方便的技巧。左移运算符 ( <<
) 将允许您将一点推到特定的二进制位置。将其与根据同一类中的其他值声明枚举值的能力相结合,您将拥有一个非常易于阅读的位标志枚举声明性语法。
[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
}
回答by Neal
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);
Using this, for 8bit binary, I use this to make a static class and it puts it into the clipboard.. Then it gets pasted into the project and added to the Using section, so anything with nb001010 is taken out of a table, at least static, but still... I use C# for a lot of PIC graphics coding and use 0b101010 a lot in Hi-Tech C
使用它,对于 8 位二进制文件,我使用它来创建一个静态类并将其放入剪贴板。至少是静态的,但仍然......我使用 C# 进行大量 PIC 图形编码,并在高科技 C 中大量使用 0b101010
--sample from code outpt--
--来自代码输出的示例--
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
:-) 尼尔
回答by Roy Tinker
Adding to @StriplingWarrior's answer about bit flags in enums, there's an easy convention you can use in hexadecimal for counting upwards through the bit shifts. Use the sequence 1-2-4-8, move one column to the left, and repeat.
添加到@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
}
Scan down starting with the right column and notice the pattern 1-2-4-8 (shift) 1-2-4-8 (shift) ...
从右列开始向下扫描并注意模式 1-2-4-8 (shift) 1-2-4-8 (shift) ...
To answer the original question, I second @Sahuagin's suggestion to use hexadecimal literals. If you're working with binary numbers often enough for this to be a concern, it's worth your while to get the hang of hexadecimal.
为了回答最初的问题,我第二个@Sahuagin 的建议是使用十六进制文字。如果您经常使用二进制数来解决这个问题,那么花点时间掌握十六进制是值得的。
If you need to see binary numbers in source code, I suggest adding comments with binary literals like I have above.
如果您需要在源代码中查看二进制数,我建议像上面那样添加带有二进制文字的注释。
回答by RaoulRubin
Basically, I think the answer is NO, there is no easy way. Use decimal or hexadecimal constants - they are simple and clear. @RoyTinkers answer is also good - use a comment.
基本上,我认为答案是否定的,没有简单的方法。使用十进制或十六进制常量 - 它们简单明了。@RoyTinkers 的回答也很好 - 使用评论。
int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8; // 000000001000
The others answers here present several useful work-a rounds, but I think they aren't better then the simple answer. C# language designers probably considered a '0b' prefix unnecessary. HEX is easy to convert to binary, and most programmers are going to have to know the DEC equivalents of 0-8 anyways.
此处的其他答案提供了几个有用的工作轮次,但我认为它们并不比简单的答案更好。C# 语言设计者可能认为“0b”前缀是不必要的。HEX 很容易转换为二进制,大多数程序员无论如何都必须知道 0-8 的 DEC 等价物。
Also, when examining values in the debugger, they will be displayed has HEX or DEC.
此外,在调试器中检查值时,它们将显示为十六进制或十进制。
回答by totymedli
If you look at the language feature implementation statusof the .NET Compiler Platform ("Roslyn") you can clearly see that in C# 6.0 this is a planned feature, so in the next release we can do it in the usual way.
如果您查看.NET 编译器平台(“Roslyn”)的语言功能实现状态,您可以清楚地看到,在 C# 6.0 中,这是一个计划中的功能,因此在下一个版本中我们可以按照通常的方式进行。