byte的取值范围为啥是[-128~127]

byte的取值范围为啥是-128~127

沐阳gg

已于 2023-02-15 14:13:11 修改

阅读量3.7k
收藏 73

点赞数 37
分类专栏: java java数据structure 文章标签: java 数据结构 c语言
版权

java
39 篇文章4 订阅
订阅专栏

java数据structure
2 篇文章0 订阅
订阅专栏
今天收到铁子问了一个问题,在java中的byte的取值范围为啥是[-128,127],而不是[-127,127];于是针对这个问题继续水一篇博客;

一、解释为啥会提出[-127,127]的问题
在字节中大家应该都知道有8位,其中第一位是符号位,剩下的七位是用来表示二进制数值的,于是就有了如下答案:

11111111==>-127
01111111==>127
[-127,127]
这是[-127,127]的说法,那为什么说是[-128,127]呢,这里我们来详细聊一聊

二、基础概念
在了解真正的答案之前,我们需要先了解几个基本概念,因为我们是人,不是机器,我们只知道正负,但是并不了解他在机器中的原理;

1、机器数:
表示一个数在计算机的二进制表示形式。机器数它是带符号的,在最高位用来存放符号,正数为0,负数为1;

举个十进制转换为二进制的例子:

十进制的+2:00000010
十进制的-2:10000010
这上面一长串二进制就是机器数

2、真值
在上面机器数的举例当中,我们将最高位设置成了符号位,例如10000010,最高的位代表负数,真正的值为-2

所以将带符号表示的机器数对应的真正的数值称为真值。

3、原码
表示的意思是:符号位加上真值的绝对值,就是用最高位表示符号,其他位表示值;

举个例子:
+1的原码:00000001
-1的原码:10000001
除开最高位的符号,我们可以得到剩下七位最高为1111111,所以可以组成[-127,127],这就是最开始大家理解到的程度;也是人脑最容易理解的方式;

4、反码:
正数【最高位为0】的反码是本身,负数【最高位为1】的反码是在原码的基础上,最高位的符号位不变,其他位取反;

举个例子:
+1的反码(正数取本身):00000001===>00000001
-1的反码(负数除开最高位,其他取反):10000001===>11111110
5、补码
正数的补码是本身;

负数的补码是在其原码的基础上,符号位不变,其余各位取反【得到反码】,最后在反码上+1
注意这里符号位也参与运算

举个例子:
+1的原码:00000001
+1的反码:00000001
+1的补码:00000001

-1的原码:10000001
-1的反码:11111110
-1的补码:11111111
总结:原码是人脑能理解的,而反码和补码需要转换为原码作为人类的我们才能看懂;正数的反码和补码都是本身,负数的反码和补码和本身不一样,请参考上面;

三、为什么byte类型的取值范围是[-128,127]
正数最大的原码:
01111111
正数最大的反码:
01111111
正数最大的补码:
01111111
没有任何差异,所以最大的肯定是127;主要是负数我们需要了解为啥是-128

1、为什么要提到补码和反码
总所周知,我们用计算机用得最多的计算方式是+、-、*、/,这个也是计算机最基本的最基础的运算,但是,这个设计肯定是要越简单越好,用+、-算法来举例,这是2种计算方法,有没有办法当作一种算法来计算呢,可以的,就是减法可以当作是加上了一个负数,比如1-1=1+(-1)=0,将最高位的符号位参与计算,所以计算机里面没有减法,就只需要做加法的计算原理就行了;

举例:

十进制的加法:1+1=2;
二进制的加法:1+1=00000001+00000001=00000010=2;

十进制的减法:1-1=0;
二进制的减法:1-1=1+(-1)=00000001+10000001=10000010=-2
从上面的运算中,我们使用的是原码的方式进行计算,加法没问题,但是减法直接懵逼了叭,结果居然为-2,简直不合理啊,于是针对这个情况(原码做减法),出现了反码,我们来看看效果:

十进制的加法:1+1=2;
二进制的原码加法:1+1=00000001+00000001=00000010=2;
二进制的反码加法:1+1=00000001+00000001=00000010=2;

十进制的减法:1-1=0;
二进制的原码减法:1-1=1+(-1)=00000001+10000001=10000010=-2;
二进制的反码减法:1-1=1+(-1)=00000001+11111110=11111111;
这里可以得到反码11111111,然后我们需要将其反码换成人看得懂的原码,11111111===>10000000=-0

通过反码计算确实可以得到正确答案,这也就是为什么要有反码的出现,但是,这里还有一个小问题,那就是这个“0”,从人的角度来说+0和-0效果一样,但是0带符号没有任何意义,在计算机系统有10000000和00000000这两个机器码都表示0;

于是补码的出现,解决了0的符号以及两个编码的问题

十进制的减法:1-1=0;
二进制的原码减法:1-1=1+(-1)=00000001+10000001=10000010=-2;
二进制的反码减法:1-1=1+(-1)=00000001+11111110=11111111;
二进制的补码减法:1-1=1+(-1)=00000001+11111111=00000000;
得到结果是00000000,为什么是00000000而不是100000000,因为一个字节只能装8位,现在后面的8位就是00000000,于是就得到了0,存在问题的-0就不存在了;

那么-128的算法可以这样算:

十进制:-1+(-127)=-128
二进制原码:10000001+11111111
二进制反码:11111110+10000000
二进制补码:11111111+10000001=10000000[只保留8位]
于是现在10000000就可以用来占-128这个位置啦。

所以在原码和反码中,结果是[-127,127];

机器使用补码,所以就出现了[-128,127];

四、总结
使用补码可以解决0的符号问题,且能多一个最低数-128,这就是为什么byte的范围是[-128,127]
————————————————

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/qq_52545155/article/details/128664751

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值