一、
Java整数数据类型中1个byte占用8位,取值范围是[-128,127],即-~(-1)。0~127的二进制表示形式:0000 0000 ~ 0111 1111;-1 ~-127~ -128的二进制标识形式:1111 1111 ~ 1000 0001 ~ 1000 0000。其中1111 1111 ~ 1000 0001 ~ 1000 0000分别是-1 ~-127~ -128的补码形式。
【疑问】byte整数型的取值范围为何是[-128,127],却不是[-127,127]呢?
二、原理
只有有符号的整数才有原码、反码和补码,其他的类型一概没有。1个字节(8位)能表示=256个数,它在计算机中的储存如下:用最高位表示符号位,0表示正数,1表示负数;剩下的7位用来储存数的绝对值,能表示27个数的绝对值,再考虑正负两种情况,27*2=256个数。首先定义0在计算机中储存为00000000,对于正数我们依然可以像无符号数那样换算从00000001到01111111依次表示1到127。那么这些数对应的二进制码就是这些数的原码。到这里很多人就会想:那负数是不是从10000001到11111111依次表示-1到-127。如果这样的话一共就只能表示255个数了,比预期少1个,因为10000000的情况没有考虑在内。实际上,10000000在计算机中表示最小的负整数,就是这里的-128。计算机并不是从10000001到11111111依次表示-1到-127,而是刚好相反,从10000001到11111111依次表示-127到-1。负整数在计算机中是以补码形式储存的。补码等于反码加1。所谓反码就是把负数的原码(不包含符号位)取反,各个数位按位取反就是1就换成0,0就换成1。如-1的原码是10000001,那么-1的反码就是11111110,而补码就是在反码的基础上加1,即-1的补码是11111110+1=11111111。因此我们可以算出-1在计算机中是按11111111储存的。
【举个例子】
十进制 → 二进:29 → 0001 1101。
有符号的整数 | 原码 | 反码 | 补码 | 规则 |
29 | 0001 1101 | 0001 1101 | 0001 1101 | 正数的原码、反码和补码相同 |
-29 | 1001 1101 | 1110 0010 | 1110 0011 | 负数补码是在反码上加1 |
三、总结
计算机储存有符号的整数时,是用该整数的补码进行储存的。
【概念】
1、原码:在数值前加一位符号位的二进制表示法。
2、反码:正整数的反码与原码相同;负数的反码等于原码(除符号位外)各数位取反。
3、补码:正整数的补码与原码相同;负数补码等于反码加1。
【规律】
1、0的源码和补码都是0;
2、正数的原码、反码和补码相同;
3、一定记得:负数用补码来表示。
【运算】
原码不能直接参与运算。
1、X+Y= X补 + Y补
2、X-Y = X补 + (-Y)补
其中,(-Y)补 = 对 Y补 的每一位(包括符号位)求反,末位加1。