2014-07-24 31 views
0

我正在读取一个24位值,目前变为uint32_t变量。计算两个这样的变量之间的差异,并思考“它是无符号的!为什么这会溢出一个问题?!”,我意识到这些值已经超出了包含它们的变量的大小。C无符号整数比较 - 环绕自定义位数

这是一个计数器,所以人们知道它比另一个'大',虽然可能溢出了。因此,0x1 - 0x2 = 0xFFFFFFFF,但应该是0x00FFFFFF

我该怎么处理这件事?

  • 定义类型uint24;
  • if/else在做适当的算术之前哪个更大;
  • 我还没有想到的其他东西?

'最好'应该被解释为'最佳实践'/'最可读'/'最安全'。

+1

1.您能否给您所遇到的问题的例子吗?有输入和预期结果。 2.你想减法的结果是有符号还是无符号的? – interjay

+0

@interjay结果也是无符号的 - 这是一个计数器,所以一个是已知的更大;签名的结果将毫无意义/ MSb浪费。 – OJFord

+0

然后我没有看到问题是什么。如果从较大的数字中减去较小的数字,则不会发生溢出。 – interjay

回答

6

要减去(或添加)两个数字并使结果环绕无符号24位数字的范围,请执行二进制操作,结果为0xFFFFFF,即(x-y) & 0xFFFFFF。例如:

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

那真是愚蠢的我。 – OJFord

1

起初,你可以使用比较操作!===>>=<<=。你不需要做这样的num1 - num2,如果你想比较...

无论如何,如果它真的necesaary,只是用位与

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

(live example)

输出:

0x00fffffc 

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

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

+1

是的,它被指定为无符号类型。 (该标准大致描述为:令** M **为该类型的精度,则表达式的结果为算术正确结果模** 2^M **;这实际上是2的补码。) – mafso

+0

@mafso是的,但严格来说,标准并不强制2> o < – ikh

+0

不是那个词,是的。我的观点是,即使在非2的补充机器上,你的代码也能保证工作。 – mafso