右移C中的负数

时间:2009-12-07 05:09:39

标签: c bit-shift negative-number

我有C代码,我在其中执行以下操作。

int nPosVal = +0xFFFF;   // + Added for ease of understanding
int nNegVal = -0xFFFF;   // - Added for valid reason

现在我尝试

printf ("%d %d", nPosVal >> 1, nNegVal >> 1);

我得到了

32767 -32768

这是预期的吗?

我能够想到像

这样的东西
65535 >> 1 = (int) 32767.5 = 32767
-65535 >> 1 = (int) -32767.5 = -32768

即,-32767.5四舍五入为-32768。

这种理解是否正确?

6 个答案:

答案 0 :(得分:38)

看起来您的实现可能正在使用两个补码进行算术位移。在这个系统中,它将所有位向右移动,然后用最后一位的副本填充高位。因此,对于您的示例,将int视为32位:

nPosVal = 00000000000000001111111111111111
nNegVal = 11111111111111110000000000000001

转变之后,你得到了:

nPosVal = 00000000000000000111111111111111
nNegVal = 11111111111111111000000000000000

如果将其转换回十进制,则分别得到32767和-32768。

实际上,右移向负无穷大转移。

编辑:根据最新draft standard的第6.5.7节,负数上的这种行为取决于实现:

E1的结果> > E2是E1右移E2位位置。如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1 / 2 E2 的商的整数部分。如果E1具有有符号类型和负值,则结果值是实现定义的。

他们声明的rational

C89委员会肯定了K& R授予的实施自由,不要求签署权利转移操作签署延期,因为这样的要求可能减慢快速代码,因为符号扩展转换的有用性是微不足道的。 (转移负二的补码 整数算术右边一个地方和除以2相同!)

所以它的实现依赖于理论。在实践中,我从未见过实现在左操作数被签名时进行算术移位。

答案 1 :(得分:18)

不,在使用整数时,不会得到像0.5这样的小数。当您查看两个数字的二进制表示时,可以很容易地解释结果:

      65535: 00000000000000001111111111111111
     -65535: 11111111111111110000000000000001

位向右移位一位,并在左侧延伸(请注意,这取决于实现,感谢Trent):

 65535 >> 1: 00000000000000000111111111111111
-65535 >> 1: 11111111111111111000000000000000

转换回十进制:

 65535 >> 1 = 32767
-65535 >> 1 = -32768

答案 2 :(得分:7)

C规范未指定符号位是否被移位。它取决于实现。

答案 3 :(得分:3)

当你右移时,最低有效位被丢弃。

0xFFFF = 0 1111 1111 1111 1111,右移给0 0111 1111 1111 1111 = 0x7FFF

-0xFFFF = 1 0000 0000 0000 0001(2s补码),右移至1 1000 0000 0000 0000 = -0x8000

答案 4 :(得分:3)

A-1:是的。 0xffff>> 1是0x7fff或32767.我不确定-0xffff是做什么的。这很特别。

A-2:转移与分裂不是一回事。它是位移 - 一个原始的二进制操作。它有时可以用于某些类型的划分是方便的,但并不总是相同。

答案 5 :(得分:2)

在C级别下,计算机的CPU核心完全是整数或标量。虽然现在每个桌面CPU都有一个FPU,但情况并非总是如此,即使在今天,嵌入式系统也没有浮点指令。

今天的编程范例和CPU设计和语言可以追溯到FPU可能不存在的时代。

因此,CPU指令实现定点操作,通常被视为纯整数操作。只有当程序声明 float double 的项目时,才会存在任何分数。 (好吧,你可以将CPU操作用于分数的“固定点”,但现在这种情况并非常罕见。)

无论多年前语言标准委员会要求什么,所有合理的机器都会在有符号数的右移上传播符号位。无符号值的右移在左侧以零的形式移位。向右移出的位落在地板上。

为了进一步了解,您需要调查“二次补码算术”。