0

从这里链接计算整数的符号

int v;      // we want to find the sign of v
int sign;   // the result goes here 

sign = v >> (sizeof(int) * CHAR_BIT - 1);
// CHAR_BIT is the number of bits per byte (normally 8)

如果我理解正确,如果 sizeof(int) = 4 bytes => 32 bits

MSB 或第 32 位为符号保留。因此,我们右移 (sizeof(int) * CHAR_BIT - 1) 并且所有位都从右侧脱落,只留下索引 0 处的前一个 MSB。如果 MSB 为 1 => v 为负数,否则为正数。

我的理解正确吗?

如果是这样,那么有人可以向我解释一下作者在这里所说的这种特定于架构的方法是什么意思:

这个技巧有效,因为当有符号整数右移时,最左边的位的值被复制到其他位。当值为负时,最左边的位为 1,否则为 0;所有 1 位都给出 -1。不幸的是,这种行为是特定于架构的

这对于 32 位或 64 位架构有何不同?

4

2 回答 2

3

我相信“架构依赖”是基于处理器支持的移位操作类型。x86(16、32 和 64 位模式)支持“算术移位”和“逻辑移位”。算术变体在移位时将移位值的最高位向下复制,逻辑移位不会,它用零填充。

但是,为了避免编译器必须按照以下方式生成代码:

int temp = (1 << 31) & v; 
sign = v;
for(i = 0; i < 31; i++)
  sign = temp | (sign >> 1);

避免架构只有“逻辑”转变的问题。

大多数架构都有这两种变体,但有些处理器没有。(抱歉,我找不到显示哪些处理器有和没有两种移位变体的参考资料)。

64 位机器也可能存在无法区分 64 和 32 位移位的问题,因此从数字移入高 32 位,而不是较小的符号位。不确定这样的处理器是否存在。

另一部分当然是确定一个补码中-0的符号实际上是符号的“0”还是“-1”结果。这真的取决于你想要做什么。

于 2013-06-01T08:12:53.293 回答
0

它是“依赖于架构的”,因为在 C++ 中,负值右移的效果是实现定义的(在 C 中它会产生未定义的行为)。反过来,这意味着您不能依赖结果,除非您已阅读并理解编译器的功能文档。就个人而言,我相信编译器会为v < 0 ? -1 : 0.

于 2013-06-01T17:41:09.087 回答