>"操作的有关问题【求大神,不是那么容易解决的】" /> >"操作的有关问题【求大神,不是那么容易解决的】 - 网页学习体会" />

关于位运算符"<<"和">>"操作的有关问题【求大神,不是那么容易解决的】

关于位运算符"<<"和">>"操作的问题【求大神,不是那么容易解决的】
今天看了一下关于位运算的一些东西,动手很了一个很简单的程序。
程序的功能是输入一个数,然后计算出它在二进制数的情况下为1的位数的个数。
C/C++ code

int iNumber;
while(true)
{
    int iCount = 0;
    scanf("%d", &iNumber);
    if ( 0 == iNumber )
    {
        printf("iNumber is 0 exit ! \n");
        break;
    }
    while( 0 != iNumber )
    {
        iCount += iNumber & 1;
        iNumber >>= 1;
    }
    printf("count : %d \n", iCount);
}



运行的时候发现一个问题。当输入为一个正数的时候输出为正确的。
但是当输入为一个负数的时候就会进入一个死循环。
例输入为:-9
调试以后发现:
iNumber iCount
0xfffffff7 0x00000000
0xfffffffb 0x00000001
0xfffffffd 0x00000002
0xfffffffe 0x00000003
0xffffffff 0x00000003
0xffffffff 0x00000004
0xffffffff 0x00000005
.......... ..........
0xffffffff ++iCount

可以看到当iNumber为0xffffffff以后再对它进行 ">>"移位操作的时候没有作用。
但是在iNumber为正数的情况下是没有这个问题的。

于是我想到可能是数符号的问题。
于是将程序改了一下:
C/C++ code

unsigned int iNumber;  //只是改了这里讲iNumber改为无符号数。
while(true)
{
    int iCount = 0;
    scanf("%d", &iNumber);
    if ( 0 == iNumber )
    {
        printf("iNumber is 0 exit ! \n");
        break;
    }
    while( 0 != iNumber )
    {
        iCount += iNumber & 1;
        iNumber >>= 1;
    }
    printf("count : %d \n", iCount);
}



运行以后负数的问题解决啦。没有出现上面的死循环。输出也是正确的。

然后我又想到了在"<<"这个运算符上面会不会出现这个问题。
又将程序改了一下:
C/C++ code

int iNumber;            //亲,这里不是无符号的啦
while( true ){
    int iCount = 0;
    scanf("%d", &iNumber);
    if ( 0 == iNumber )
    {
        printf("iNumber is 0 exit ! \n");
        break;
    }
    while( 0 != iNumber )
    {
        iCount +=  0 != ( iNumber & 0x80000000 ) ? 1 : 0 ;
        iNumber <<= 1;
    }
    printf("count : %d \n", iCount);
}


输入正数和负数都是OK的,输出也是正确。

如此问题来了:
为什么iNumber为有符号-1(0xffffffff)的时候对他进行">>"操作会没作用,而"<<"符号操作的时候却是正确呢?
而根据这个运算符的作用 ">>"是向右移,高位补零。"<<"是左移,低位补零。上面的">>"操作显然是不合理的。
如果是符号的问题,还请大神提供理论支持!如果不是,求解释。


系统:windows xp 32位 调试工具:VS2008

我只是在XP下面测试了一下,没有linux系统,不知道是个什么情况。

不知道同志们有没有遇到这种情况,还请同志们不吝赐教,重在交流~~~~


------解决方案--------------------
谁说右移是补0的,右移是补0还是补符号位根据实现,左移补0就不用说了
------解决方案--------------------
右移的时候,符号位是不变的.