java整形取值范围的计算

整形取值范围图如下:

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,这种推导其他整形也类似。

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值