整形取值范围图如下:
1.公式
-2^(n-1) ~ 2^(n-1)-1 其中n表示该类型共多少个bit位
2.疑惑
按照我的想法最大的取值范围是符号位取0,其他位取1;而最小取值范围只在最大范围基础上符号取反即可,也就是应该是-2^(n-1)-1 ~ 2^(n-1)-1 ,例如:byte类型,最大取值范围01111111,值为127,最小取值11111111,值为-127,也就是范围是-127-127。而这与我们所学的公式矛盾了,根据公式得出的结果应该是-128~127,那么为什么这里多出了-128呢?让我们带着疑惑往下看。
3.原码、反码、补码的引入
我们知道在计算机存储数据用的是二进制数,而我们用二进制表示一个数字例如127,由两部分组成:第一部分是符号位由于127是正数所以符号位为0,第二部分是数值部分127可以二进制表示为1111111,因此两部分组合起来是01111111,这种表示数字的方法得出的二进制数就是原码。
我们不妨用原码来进行一个计算 1-1,但是计算机底层只会做加法,所以我们计算的式子可以表示成1+(-1), 1的原码是00000001,-1的原码是10000001,假定1和-1都是byte类型,我们这里针对byte类型的范围进行讨论,其他整形类似。
00000001
+ 10000001
------------------
10000010
1+(-1)的结果是10000010,也就是-2,这显然不正确。因此为了解决这个问题,计算机大牛们发明出了反码,规定正数的反码是其本身,而负数的反码在原码的基础上符号位不变,其他位取反(1变0,0变1)
还是1+(-1),
1的原码是00000001, 补码就是00000001
-1的原码是10000001,反码就是11111110
00000001
+ 11111110
------------------
11111111
得到的是反码和为11111111,转换为原码是10000000,也就是-0,结果只看数值的话是0完全没有问题,可是0就是0,我们不希望还有-0这种存在,于是为了解决这个问题,大牛们又发明了补码,规定正数的补码是其本身,而负数的补码是反码+1。
1的原码是00000001, 补码就是00000001
-1的原码是10000001,反码就是11111110,补码是11111111
00000001
+ 11111111
------------------
100000000
由于100000000已经有9位了,而我们char类型只有8位,因此最高位1被丢弃,结果是00000000,补码是00000000,其对应原码也是00000000,那么结果就是0,这回1+(-1)计算的结果没有问题了。
4.解释疑惑
在引入了原码、反码、补码的概念之后,我们再对之前的疑惑进行解答。
我们自己期望范围是-127-127。根据公式得出的结果确是-128~127。
我们不妨把目光放在0上,对于能表示0的值来说,明明可以有+0、-0,
但是我们的范围内只要一个0,也就是+0,原码是00000000,它代表了-128~127中的0这个值,
那么-0,原码为10000000去哪了?它和多出的这个-128有什么关系?
-0的原码为10000000,补码为00000000
-128的原码应为110000000,但是byte只有8位,舍弃最高位为10000000,因此补码也为00000000
我们不难看出对于byte来说,-0和-128的原码和补码在byte类型截断后的限制下完全一致,所以在byte类型里面我们可以使用-0也就是10000000来表示-128,因此比我们自己期望范围-127-127多出一个-128,byte的真正范围在-128~127,这种推导其他整形也类似。
标签:java,整形,补码,127,128,反码,byte,取值,原码 From: https://blog.csdn.net/qq_59153009/article/details/139213193