若有错误,欢迎指出!
我们都知道 对 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
因为产生了溢出,所以与原来的值一样。
网友评论