int类型整数占四个字节,所能表示的范围为 -2147483648~~2147483647。假如当数据溢出的时候,有趣的事情发生了
#include <stdio.h>
int main(int argc, const char * argv[])
{
int a=0x80000000;//所能表示最小数 -2147483648
int b=0x7fffffff;//表示的最大数 2147483647
printf("%d %d\n",a-1,b+1);
return 0;
}
输出为 2147483647 -2147483648
也就是说最小数溢出后是最大数,最大数溢出后是最小数。可是为什么呢?这和计算机里面补码运算有关,如下:
-2147483648十六进制:0x80000000
-2147483648二进制补码 0b10000000,00000000,00000000,00000000
-1二进制补码 0b11111111, 11111111, 11111111, 11111111
相加 0b01111111, 11111111, 11111111, 11111111
所以结果是最大值 2147483647,同理可以求得最大值溢出后是最小值。
知道了这个后,我们继续讨论<< >>运算。
左移
当按位左移 m位时候,右端补 m 个 0,相当于乘上 2^m ,左移会引起符号位改变。
#include <stdio.h>
int main(int argc, const char * argv[])
{
int a=0xffffffff;
int b=0x7fffffff;
for(int i=1;i<33;i++)
printf("%2d %12d %12d\n",i,a<<i,b<<i);
return 0;
}
输出列表
1 -2 -2
2 -4 -4
3 -8 -8
4 -16 -16
5 -32 -32
6 -64 -64
7 -128 -128
8 -256 -256
9 -512 -512
10 -1024 -1024
11 -2048 -2048
12 -4096 -4096
13 -8192 -8192
14 -16384 -16384
15 -32768 -32768
16 -65536 -65536
17 -131072 -131072
18 -262144 -262144
19 -524288 -524288
20 -1048576 -1048576
21 -2097152 -2097152
22 -4194304 -4194304
23 -8388608 -8388608
24 -16777216 -16777216
25 -33554432 -33554432
26 -67108864 -67108864
27 -134217728 -134217728
28 -268435456 -268435456
29 -536870912 -536870912
30 -1073741824 -1073741824
31 -2147483648 -2147483648
32 -1 2147483647
Program ended with exit code: 0
注意当移动位数m大于32时,移动 m%32位
右移
右移m位,右端m个位数丢失,左端不断补充符号位。最高位u右移和左移区别在于最高位符号位不会改变。
#include <stdio.h>
int main(int argc, const char * argv[])
{
int a=0x80000000;
int b=0x7fffffff;
for(int i=1;i<33;i++)
printf("%2d %12d %12d\n",i,a>>i,b>>i);
return 0;
}
1 -1073741824 1073741823
2 -536870912 536870911
3 -268435456 268435455
4 -134217728 134217727
5 -67108864 67108863
6 -33554432 33554431
7 -16777216 16777215
8 -8388608 8388607
9 -4194304 4194303
10 -2097152 2097151
11 -1048576 1048575
12 -524288 524287
13 -262144 262143
14 -131072 131071
15 -65536 65535
16 -32768 32767
17 -16384 16383
18 -8192 8191
19 -4096 4095
20 -2048 2047
21 -1024 1023
22 -512 511
23 -256 255
24 -128 127
25 -64 63
26 -32 31
27 -16 15
28 -8 7
29 -4 3
30 -2 1
31 -1 0
32 -2147483648 2147483647
Program ended with exit code: 0
还有一点左移m位后溢出终值为 0,右移 溢出 负数最小终值 -1,正数终值 0