-2147483648的绝对值问题

2017-04-19  本文已影响201人  永远保持一颗进取心

若有错误,欢迎指出!

我们都知道 对 int 型数据 -2147483648 求绝对值,结果仍为 -2147483648。 这是为什么呢?答案是:溢出

问题重现:
int main(int argc, char *argv[]) {
    int a = 0x80000000;
    printf("a = %d   |a| = %d\n",a, abs(a));
    return 0;
}

输出为:
a = -2147483648   |a| = -2147483648

那我们应该怎么去理解了?

第一:我们要理解 int(32位) 型数据的值域为[-231 231 - 1]

因为整数在电脑中都是以补码的形式存在,整数(包括0)的补码是本身,负数的补码的 反码+1 。以 1byte 的数据为例,正数和负数的二进制补码表示为对比为:
1=0b00000001 -1=0b11111111
2=0b00000010 -2=0b11111110
3=0b00000011 -3=0b11111101
127=0b01111111 -127=0b10000001
此时对于负值,仍有 0b1000000 去表示 -128, 当是正数补码已经没有二进制数去表示 127 此时 加1 就会产生溢出
所以对于 int(32位)型数据同理。

第二:我们要知道 -2147483648 是 int 型数据(32位)的负数的最小值

-2147483648 的 十六进制为 0x80000000 ,对其求绝对值 反码+1
反码 = 0x7fffffff 则 补码(绝对值)= 反码+1=0x80000000
因为产生了溢出,所以与原来的值一样。

上一篇 下一篇

猜你喜欢

热点阅读