【问题标题】:C unsigned int comparison - wrap around on custom bit numberC unsigned int 比较 - 环绕自定义位数
【发布时间】:2014-09-16 00:42:50
【问题描述】:

我正在读取一个 24 位值,目前是一个 uint32_t 变量。

在计算两个这样的变量之间的差异时,我的头撞到了墙上,并想“它是无符号的!为什么这个溢出是个问题?!”,我意识到这些值溢出了包含它们的变量的大小。

这是一个计数器,因此已知一个比另一个“大”,尽管可能已经溢出。

因此,0x1 - 0x2 = 0xFFFFFFFF,但应该是0x00FFFFFF

我应该如何最好地处理这个问题?

  • 定义一个类型uint24;
  • if/else 在进行适当的算术运算之前较大;
  • 还有什么我没想到的?

“最佳”应解释为“最佳实践”/“最易读”/“最安全”。

【问题讨论】:

  • 1.你能举一个你遇到的问题的例子吗?有输入和预期结果。 2. 减法的结果是有符号还是无符号?
  • @interjay 结果也是无符号的——这是一个计数器,所以知道一个更大;签名结果将毫无意义/浪费 MSb。
  • 那我不明白是什么问题。如果从较大的数字中减去较小的数字,则不会溢出。
  • @interjay 好吧0x1 - 0x2 将是0xFFFFFFFF,但应该是0xFFFFFF
  • 我不明白你为什么使用- 运算符来比较两个数字,因为你有很多关系/相等运算符<<=!= 等等。我同意一些独立的示例会很有用。

标签: c types unsigned integer-arithmetic


【解决方案1】:

首先,您可以使用比较运算符!===>>=<<=。如果你想比较,你不需要像num1 - num2这样......

无论如何,如果真的需要,只需使用按位与

uint32_t n1 = 1, n2 = 5;
printf("0x%08x", (n1 - n2) & 0x00ffffff);

(live example)

输出:

0x00fffffc

如您所知,0xfffffc 表示 24 位有符号整数中的 -4

(请注意,2 的补码不是由 C 标准指定的;我的代码可能无法在非 2 的补码系统中工作。)

【讨论】:

  • 是的,它是为无符号类型指定的。 (标准大致描述为:设 M 为类型的精度,则表达式的结果是算术正确的结果模 2^M;实际上是 2补充。)
  • @mafso 是的,但严格来说,标准并不强制 2 的 >o
  • 不是那个词,是的。我的意思是,即使在非 2 的补码机器上,您的代码也可以保证工作。
【解决方案2】:

要减去(或相加)两个数字并将结果环绕在无符号 24 位数字的范围内,请使用 0xFFFFFF 对结果进行二进制与,即 (x-y) & 0xFFFFFF。例如:

(0x1 - 0x2) & 0xFFFFFF == 0xFFFFFF

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 2020-08-28
    相关资源
    最近更新 更多