【问题标题】:C# bitwise addition and subtraction like in CC# 按位加法和减法,就像在 C 中一样
【发布时间】:2012-04-30 09:45:15
【问题描述】:

我正在编写一个 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# 中处理二进制数的基本策略吗?

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

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

【问题讨论】:

  • 你如何想象按位减法和整数减法是不同的?此外,如果将数字 10 存储在 int 中,则该数字是十进制的 10,永远不会是二进制的 10。
  • 不要发布四叉树的一部分,而是用 C# 和 C 编写一个小的控制台应用程序并尝试展示具体的差异。
  • 我的回复评论越来越长,所以我将尝试澄清原始帖子,感谢您的 cmets,我以前从未使用过二进制文件。 C 和 C# 可能工作方式相同,只是我不明白它们是如何工作的,所以我也会在控制台应用程序上工作。
  • 没有“按位减法”之类的东西。减法只是 C# 或 C 中的减法。
  • 当我在四叉树中有一个四边形并按照参考文件中的描述分配了二进制地址时,它的左侧邻居是四边形的地址 - 最小四边形宽度。因此,如果您允许 4 级树,则四边形 #011 的左侧邻居是 #011 - #001。该操作的名称是什么?

标签: c# binary bit-manipulation


【解决方案1】:

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

  • 文字 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# 中处理二进制数的基本策略吗?

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

【讨论】:

  • 谢谢!在短暂的头痛之后,这很有意义:)
【解决方案2】:

为什么感兴趣的行在 C 中执行按位减法,但在 C# 中执行整数减法。

他们都应该这样做。为什么你不这么认为?那么按位减法是什么意思?

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

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

我想我正在寻找的是在 C# 中处理二进制数的一些基本策略。

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

【讨论】:

  • 我不这么认为,因为我的代码完全错误。我的代码太长,无法发布,所以我将编写一个简单的控制台应用程序。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 2013-01-16
    • 2013-11-03
    • 2011-02-27
    • 2023-03-31
    相关资源
    最近更新 更多