C ++向左移负数

时间:2019-04-10 14:33:37

标签: c bit-manipulation

如下所示,该代码存在错误。当输入a = -1,b = 1时,其中一行存在运行时错误。您能帮我理解(a和b)如何变成INT_MIN吗?

在我的理解中,-1表示为32位二进制格式0xFFFFFFFF,而1表示为32位格式0x00000001,因此(-1&1)将变为0x00000001。而且我的python命令还显示了'0b1'作为结果。为什么报告INT_MIN错误?

int getSum(int a, int b) {
    while (b != 0) {
        int carry = (a & b) << 1;//BUG! left shift of negative value -2147483648
        a = a ^ b;
        b = carry;
    }

    return a;
}

1 个答案:

答案 0 :(得分:3)

假设这是C或C ++,则您的错误是因为Left Shifting a negative value is Undefined Behavior,并且左移有符号的值使其变得大于MAX_INT也是未定义的行为。

如果在执行此序列时检查ab的值,则会得到:

-1 1
-2 2
-4 4
...
-1073741824 1073741824

此时a&b == 1073741824。但是将其左移1等于乘以2,即得到2147483648,它比INT_MAX大。

那是未定义的行为。系统可以选择做任何事情。看来您的情况是对0x80000000进行了移位。在签名的int中,这表示INT_MIN。因此,下一次通过循环时,您将尝试左移负数,这又是未定义行为。您的系统选择将此作为例外。

通常,如果要进行位操作,最好使用无符号类型。