为什么⼀个字节的补码表⽰范围是-128~127
我们要先区分⼀下原码、反码和补码的表⽰规则:
0的表⽰:
补码的最小负数原码:有正零和负零之分,[+0]补=0000 0000,[-0]补=1000 0000;
反码:同样有两种表⽰⽅法,[+0]反=0000 0000 ,[-0]反=1111 1111;
补码:零只有⼀种表⽰⽅法,不分正负,[0]补=0000 0000;
8为⼆进制表⽰的范围为:
⼀个字节8位,如果采⽤原码表⽰正整数(含0),可以表达0-255,即 2^8=256,⼀共256种状态,从全0到全1的各种排列组合。如果要表⽰负数,则符号位需要占⽤⼀位(最⾼位,1代表负数,0代表正数),因此其绝对值最⼤范围为0-127,即2^7=128,⼀共正负各128种状态,如果不采⽤特殊处理,这时候0占⽤2个编码(10000000和00000000),数据表⽰范围为-127到-0及+0到127,这样总体上⼀个字节只有255种状态,因为其中0具有正0和负0之分,这不符合数学意义也浪费⼀个编码。
除了以上的弊端,还有个原因是,早期硬件很昂贵,⼀位或者⼀个编码的浪费都是不可饶恕的,因此⼈们想到了另⼀种编码把负0利⽤起来,即当遇到负数时,采⽤补码来表⽰就可以解决这个问题,⽽遇到正数或0时还是保留原码表⽰。因此这个负0通过补码算法处理后⾃然⽽然地被利⽤起来,⽤来表⽰-128.
补码的算法为:绝对值的原码各位取反后加1.
例1:负1的补码:绝对值的8位原码为00000001        取反:11111110        加1 :11111111        此时最⾼位被处理为1,满⾜⾼位为1代表负数的定义。
例2:负128的补码:绝对值的8位原码为10000000        取反:01111111        加1 :10000000          此时同样的最⾼位被置为1,同样满⾜⾼位为1代表负数的定义,同时原先表⽰负0的编码被利⽤起来表⽰-128。因此⼀个字节的有符号整数范围为-128到127。
综上为:
原码+反码:8位原码和反码能够表⽰数的范围是-127~127;
补码:8位补码能够表⽰数的范围是 -128~127。
(在补码中⽤(-128)代替了(-0),所以补码的表⽰范围为:(-128~0~127)共256个)