2013-04-20 39 views
-3

这里是负数按位操作:-20按位上的负数

#include <stdio.h> 

main() 
{ 
    int a = -20, b = 84; 
    printf("%d", (a>>(a &b))); 
} 

2的补二进制1100和84 10000100。所以a & b应该是100,但答案是68,整体答案是-2。

有人可以向我解释这个吗?

回答

3

如果你使用的是Windows,它应该带有一个支持二进制的计算器应用程序。 这是一个很好的可靠的计算资源。 在这里你可以选择Word这是一个int。

Negitive号码在存储器中由所有的位的左侧为1。注意到这样-20是

1111-1111-1110-1100 
= 0xFFEC 

和84是:

0000-0000-0101-0100 
= 0x0054 

而且是比较按位操作两个通过的数字检查每一位。如果两个位均为1,则结果位为1.否则为零。所以

1111-1111-1110-1100 
& 0000-0000-0101-0100 
= 0000-0000-0100-0100 
= 68 
4

-20是不是1100 。这是最有可能的(如果整数是32位,我们不是说奇数平台),11111111111111111111111111101100 。

84不是10000100 。它是1010100 。

取与他们在一起:

11111111111111111111111111101100 
& 
00000000000000000000000001010100 
= 
00000000000000000000000001000100 (68 decimal) 

然后你就换挡-20右侧68位,其中有2个问题:

  • 负整数的右移是实现定义,什么是你的编译器实施?
  • 偏移通过在值的比特数或超过该结果不确定的行为

128位整数不大可能上通用平台。 64位整数很少见,但并非不可能,但对于它们来说,68> = 64,所以你应该得到未定义的行为。现在

,这个不确定的行为可能是什么样子......

如果我们的整数都是32位的,我们这样做是x86平台(或东西足够相似)上,68应该得到被截断CPU到5位,留给你的68 & 31 = 4

然后移位数,假设SAR指令(登录保留算术右移)用于>>,我们得到(-20)SAR 4 = -2:

11111111111111111111111111101100 
SAR 
4 
= 
11111111111111111111111111111110 (-2 decimal)