2013-04-26 81 views
3

我正在阅读https://github.com/antirez/redis的redis源代码。为什么不使用VAL的补码而不是(-VAL -1)

我看到了这样的宏在SRC/ziplist.c

#define INT24_MAX 0x7fffff 

#define INT24_MIN (-INT24_MAX - 1) 

为什么不这样做呢?

#define INT24_MIN (~INT24_MAX) 
+1

'〜'会给你警告,它可能会改变符号'操作符操作值提升为int(可能意外的结果)' – 2013-04-26 05:29:01

+1

阅读本文[C不是操作符为什么会收到警告](http:// stackoverflow.com/questions/15838249/c-not-operator-why-do-i-get-a-warning)可能会对您有所帮助 – 2013-04-26 05:35:58

+0

即使添加-Wall和gcc4.8,我也无法重现警告。它与编译器相关吗? – ArkChar 2013-04-26 05:44:41

回答

5

更好的问题可能是您为什么认为(~INT24_MAX)好于(-INT24_MAX - 1)

在二进制补码机上,您从两个表达式中获得相同的结果,并且它们的计算速度与其他计算速度一样快(对于32位目标,编译器会在编译时将它们都减少到0xff800000 )。然而,在我看来,表达式(-INT24_MAX - 1)对数值概念进行了建模,即最小值比最大值的否定更好一个。

这可能没有太大的重要性,但表达式(~INT24_MAX)不是更好的客观方式,我会主张它可能不会那么好。

基本上,(-INT24_MAX - 1)可能是编码器碰巧想到的(也许因为正如我提到的那样,它模拟了数字意图),并且没有理由使用别的东西。

+0

啊,我明白了。当我第一次看到这个时,我正在考虑补充代码,甚至对它被命名为“MIN”的原因感到困惑。谢谢! – ArkChar 2013-04-26 07:57:49

5

假设,int为32位,可容纳0x7fffff,则~0x7fffff将是~0x007fffff或所有位被反转后,0xff800000

如果负整数使用2的补码表示形式,则该位模式表示负值-0x7fffff-1

如果他们使用1的补码表示,那么这个模式代表负值-0x7fffff

如果它们使用符号幅度表示,则该模式表示取值-0x7f800000

如您所见,~0x7fffff的值将取决于负整数的表示形式和可容纳值0x7fffff的类型的大小。

如果你想编写可移植的C代码,你应该避免这种情况。

相关问题