C#中的C#按位加法和减法

时间:2012-04-18 21:49:56

标签: c# binary bit-manipulation

我正在编写一个QuadTree类,我需要包含邻居搜索。我正在跟随this paper,其中包括C实现。 (我基本上把它转换成C#。)而且我遇到了麻烦,因为我不擅长使用二进制数。我需要做以下事情:

给出#100和#010,将它们组合起来得到#110。 1s永远不会重叠。现在我所做的就是存储100和10,当我添加它时它会给我110.

对#011这样的数字执行左右二进制移位。现在我正在存储011并应用>>或<<操作员。这给了我完全错误的数字,但奇怪的是我用它来找到常见的四元树父母的逻辑工作正常。

给出#011和#001将它们相加得到#100。现在我正在存储11和1,这显然根本不起作用 。

执行按位减法,与上面相同但是 - 而不是+:)

执行AND,OR和XOR。

所以,现在我将所有内容存储为一个看起来像二进制值的整数,并且数学似乎适用于AND,OR,XOR和移位。这些数字在中间是疯狂的,但我最终得到了正确的答案。

我正在尝试一个实现,我存储整数值,这是二进制数的值,但我必须来回转换很多,这特别是一个痛苦,因为我在一个整数表示之间转换数字的值和二进制数本身的字符串表示。每隔一行代码创建一个新字符串就会成为一场性能噩梦。

你们可以推荐一个在C#中使用二进制数的基本策略吗?

P.S。我不需要看到这些数字的整数表示。我真的不在乎#010 == 2,我需要做的工作将其视为#010故事的结尾。

希望这比我原来的帖子更清晰!

3 个答案:

答案 0 :(得分:3)

我希望这会消除一些困惑:

  • 文字0x00000001使用十六进制表示法表示1。
  • 文字1使用十进制表示法表示1。

以下是一些等效文字对:

 0x9 ==  9
 0xA == 10
 0xF == 15
0x10 == 16
0x11 == 17
0x1F == 31

原始整数数据类型(byte,sbyte,ushort,short,char,uint,int,ulong,long)总是以二进制格式存储在计算机的内存中。以上是以上用五位表示的值:

 1 == #00001
 9 == #01001
10 == #01010
15 == #01111
16 == #10000
17 == #10001
31 == #11111

现在,考虑一下:

unsigned int xLeftLocCode = xLocCode - 0x00000001;

以下任何一项在C#中都是等效的:

uint xLeftLocCode = xLocCode - 1;
uint xLeftLocCode = xLocCode - 0x00000001;

要将二进制#10分配给uint变量,请执行以下操作:

uint binaryOneZero = 2;   //or 0x2

十六进制表示法对于位操作很有用,因为十六进制和二进制数字之间存在一对一的对应关系。更准确地说,存在一对一的对应关系,因为16个十六进制数字中的每一个代表四个位的16种可能状态之一:

0 ==  0 == 0000
1 ==  1 == 0001
2 ==  2 == 0010
3 ==  3 == 0011
4 ==  4 == 0100
5 ==  5 == 0101
6 ==  6 == 0110
7 ==  7 == 0111
8 ==  8 == 1000
9 ==  9 == 1001
A == 10 == 1010
B == 11 == 1011
C == 12 == 1100
D == 13 == 1101
E == 14 == 1110
F == 15 == 1111

因此,很容易知道0x700FF例如,具有最低有效字节集的所有位,没有下一个最高有效字节,以及下一个最高有效字节的低三位。如果您使用文字459007来表示该值,则很难一目了然地看到这些信息。

总结:

  

你们可以推荐一个在C#中使用二进制数的基本策略吗?

了解上表,并使用十六进制文字。

答案 1 :(得分:2)

  

为什么感兴趣的行在C中进行逐位减法,而在C#中进行整数减法。

他们都应该这样做。你为什么这么想?对于按位减法你是什么意思?

  

我将二进制数10存储为整数10,而不是整数2.我可能做错了。

是的,那是错的。 #010 == 2,而不是10.

  

我想我想要的是在C#中使用二进制数字的一些基本策略。

总的来说,这些操作应与C中的操作相同。

答案 2 :(得分:1)

您标记的行与按位无关。它是数字1的直接减法(表示为十六进制双字(DWORD)或无符号长整数(C#中的uint)。