参考:https://blog.csdn.net/qq_22771739/article/details/84496115

     https://blog.csdn.net/boatalways/article/details/17027573

     https://blog.csdn.net/zhiwen_a/article/details/81192087

  Java的byte类型取值范围是-128~127为什么负数是128正数到127呢

  首先需要了解原码反码和补码

  正数的原码反码补码是一样的

  [+2]=[00000010]=[00000010]=[00000010]

  对于负数来说,它的原码反码补码就不相同

  [-2]=[10000010]=[11111101]=[11111110]

  最高位表示符号位0代表正数1代表负数,负数计算反码的规则是符号位不变,其余位取反即1变成0,0变成1,补码就是反码再加1

  为什么要设计出反码和补码

  因为计算机只有加法没有,减法,在做减法运算的时候,可以认为是加上一个负数,这样可以减少计算机电路的复杂度

  使用原码进行减法运算会出现问题,例如计算1-1,因为计算机没有加法只有减法,所以计算机自动换算成1+(-1)

  1-1=1+(-1)=[00000001]+[10000001]=[10000010]=-2 (符号位也参与运算)

  而1-1的实际结果是0

  为了解决这个问题,于是使用反码运算

  1-1=1+(-1)=[00000001]+[10000001]=[00000001]+[11111110]=[11111111]=[10000000]=-0

  通过反码计算的结果是11111111在计算一次反就成原码了,得出的结果是正确的,但是有一个问题是 00000000可以代表+0 10000000可以代表-0,其实是一样的,用2个编码实在是浪费。于是出现了补码解决0的符号以及两个编码的问题

  1-1=1+(-1)=[00000001]+[10000001]=[00000001]+[11111111]=[00000000]=[00000000]

  这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)
  使用补码,不仅仅修复了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数。这就是为什么8位二进制,使用原码或者反码表示的范围是[-127~127],而使用补码表示的范围为[-128~127]

  总结:反码是为了解决减法运算,补码是为了解决反码产生的+-0的问题

  下面来分析为什么byte型的取值范围为什么是-128~127

  1,byte占用8位,每位用0或者1表示,能够表示258(2^8)个数据

  2,这8位分为符号位(最高位)和数值位(剩余七位),符号位0表示正数,1表示负数。

  3,按上一步的理解,容易得到(+127:0111 1111、+1:0000 0001、+0:0000 0000、-0:1000 0000、-1:1000 0001、-127:1111 1111),计算机底层定义了+0(0000 0000)就是0,那么“可怜的-0”又该何去何从呢?计算机遇到这个二进制该如何处理呢?总不能把这两个都对应0吧,这显然是资源浪费。

  4,到这里我们都认为最高位是不参与计算数值的,仅仅是一个符号位,按这种思路byte的八位是无论如何也表示不出-128。而“可怜的-0”又不知道自己代表谁,不得而知“可怜的-0”就是-128。(为什么呢?凭什么呢?你说代表-128就代表-128呀!为什么不能是+128、-250、+250.......)。

  5,到这里我们已经很粗浅地回答了-128~127中的-128的由来,基本也回答了这个题目。

  6,可是然而但是——对于程序员来说,上诉的分析【首先】是结论正确,但是过程错了。错误在于——负数的二进制表示是错误的,比如-127:1111 1111,这是不对的。计算机发现了1111 1111会把它认为是-1而不是-127。【其次】没有解释为什么-0最后表示成-128。

  7,计算机基础知识补充

    <1>计算机存储有符号的整数是都是存储它们的补码。Java语言都是有符号位的。
         <2>正数和0的补码、反码是本身原码;所以对于正数来说,可以理解为不存在反码和补码。
           <3>负数的反码是是符号位不变,其它位取反;补码是在负数的基础上加1(符号位不变)。负数就是矫情啊!
         <4>计算机中用补码进行加法运算。

  8,接着从人的思考方式理解下当计算机处理1111 1111的过程,首位是1,自然是负数,而且这是补码,那么对应的原码就是,先减1,变成1111 1110,符号位不变,其他取反,变成1000 0001,也就是-1!所以从10000001到11111111依次表示-127到-1

  9,最后来解决这-128为什么可以用100000000表示

   这里我分析的是byte,它就8位。在无符号位的二进制中128的表示为1000 0000。有符号位的情况下byte好像无法表示+128或-128。

  如果我们假设byte不是占用8位,而是9位,最高位是符号位。你们-128的表示为1 10000 0000,计算其补码也是1 1000 0000,很神奇吧,一样的。-128补码尾8位就是1000 0000。那就规定1000 0000是-128的补码,而-128是没有原码和反码的,即不能利用10000 0000反推其反码和原码。

  10,如果你对9步的推导表示不太接受,那么简单就认为计算机规定了1000 0000就是-128,是一种人为设计没有什么道理可以言(据说是印度阿三设计的)。其实这么设计也是很巧妙的,在于:

  【其一】对于如果大于8位的有符号整数数据类型,-128的补码尾八位刚好是1000 0000

  【其二】比如127(0111 1111)加1(0000 0001)刚好得到-128(1000 0000),-128(1000 0000)加1(0000 00001)等于-127(1000 0001)这样从-128~127的反码首尾相连,形成了一个闭环,就像时钟一样。

  【其三】在计算机中减法运算可以转换成加法运算,比如8-1——>8+(-1)——>补码运算:(0000 1000) + (1111 1111) = (0000 0111) 刚好是7。-128+127——>(1000 0000) + (0111 1111) = (1111 1111)刚好是-1,-128的补码完美的适用于减法。

  结论

 【1】计算机中负数是用补码的形式保存、并用它参与加减法运算的,减法会被转换为加法,计算机中没有加法运算。
    【2】反码是为了解决减法运算,补码是为了解决反码产生的±0的问题。参考(https://blog.csdn.net/boatalways/article/details/17027573)
    【3】对人而言二进制所代表的值一定是从原码求出的,开头如果是1的二进制,一定要说明其实原码、反码还是补码。
    【4】在原码、反码、补码相互转换以及求对应的十进制求值时,符号位是绝不参与的,但是在加减过程中,是参与位运算的。
    【5】计算机中规定了-0对应的二进制就是0,那么-0就没有意义了,必须找一个数和它对应。
    【6】byte的最小值-128、short的最小值-32768、int的最小值-2147483648都是用对应的-0的原码来进行表示,这是人为规定的、人为规定的、人为规定的。但是这么规定又很巧妙,妙在上述10中的三点。

  

byte类型的取值为什么是-128~127的更多相关文章

  1. 为什么Java byte 类型的取值范围是-128~127 (转)

    概念:负数的补码是该 数 绝 对 值 的 原 码 按 位 取 反 ,然 后 对 整个数 加 1 步骤: 1.确定byte是1个字节,也就是8位 2.最大的应该是0111 1111,因为第一位是符号位, ...

  2. 关于JAVA中Byte类型的取值范围的推论(*零为正数,-128在计算机中的表示方法...)

    先看一段推理<*一切都是在8个比特位的前提下,讨论二进制的符号位,溢出等等,才有意义*> +124:0111 1100 -124:1000 0100 +125:0111 1101 -125 ...

  3. byte的取值范围是-128~127,那么包含-128和127吗?

    本帖最后由 王德升老师 于 2019-12-27 17:56 编辑 byte的取值范围为什么是-128~127?如果面试官问你取值范围包含127吗?1. 首先我们知道Java中byte类型是1个字节占 ...

  4. GO语言学习笔记2-int类型的取值范围

    相比于C/C++语言的int类型,GO语言提供了多种int类型可供选择,有int8.int16.int32.int64.int.uint8.uint16.uint32.uint64.uint. 1.i ...

  5. java中为什么byte的取值范围是-128到+127

    概念:java中用补码表示二进制数,补码的最高位是符号位,最高位为“0”表示正数,最高位为“1”表示负数.正数补码为其本身:负数补码为其绝对值各位取反加1:例如:+21,其二进制表示形式是000101 ...

  6. c c++各种类型的取值范围

    int类型的变量存储值从-2147483648到2147483647 //例子 #include <iostream> using namespace std; int main(void ...

  7. 为什么byte的取值范围是-128到127

    一个byte由八个位组成,如00000000,其中,符号位+数值位,前7位表示数值,第8位是符号位(0为正,1为负).这样+1就是00000001,-1就是10000001.最大的正数就是0 1111 ...

  8. loadrunner:参数类型及其取值机制

    参数类型 参数名随意取,建议取通俗易懂的名字,下面我们重点介绍一下参数的类型. ●DateTime: 很简单, 在需要输入日期/时间的地方, 可以用DateTime 类型来替代. 其属性设置也很简单, ...

  9. easyui radio 类型的取值和赋值方法

    1.HTML 文件 <tr id="client_check1"> <th>委托人证件类型:</th> <td><input ...

随机推荐

  1. Django的Form另类实现SelectMultiple

    昨天花了一天才解决,遇到的问题如下: 在forms.py里有一个如下的字段: jira_issue = forms.CharField( required=False, label=u"Ji ...

  2. Django REST framework —— 认证组件源码分析

    我在前面的博客里已经讲过了,我们一般编写API的时候用的方式 class CoursesView(ViewSetMixin,APIView): pass 这种方式的有点是,灵活性比较大,可以根据自己的 ...

  3. webview-h5页面刷新

    问题:webview 缓存了index.html页面:浏览器缓存了子页面.解决方案:网页链接后添加时间戳. 第一:避免webView缓存]在service.vue中,给url后边添加时间戳 第二:避免 ...

  4. 前端Map封装源码

    源于后台思路,简单封装了一下Map插件,方便以后使用. function Map() { this.elements = new Array(); //获取MAP元素个数 this.size = fu ...

  5. Linux——安装并配置Kafka

    前言 Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写.Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据. 这种动 ...

  6. java SSM面试题

    1. 谈谈你mvc的理解MVC是Model—View—Controler的简称.即模型—视图—控制器.MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开.MVC中的模型.视图.控制器它们 ...

  7. 36大数据和about云的文章总结

    36大数据: 白话机器学习 http://www.36dsj.com/archives/78385 基于Hadoop的数据仓库Hive 基础知识(写的很好) http://www.36dsj.com/ ...

  8. 题解 LA2889

    题目大意 多组数据,每组数据给出一个正整数 \(n\),输出第 \(n\) 大的回文数(即 \(1,2,3,\cdots\)). 分析 不难发现,\(n\) 位的回文数有 \(9*10^{\lfloo ...

  9. 文件操作时:xreadlines和readlines的区别?

    二者使用时相同,但返回类型不同,xreadlines返回的是一个生成器,readlines返回的是list

  10. Collections.synchronizedList与CopyOnWriteArrayList比较

    1.单线程方式 2.多线程版本,不安全的 ArrayList 3.多线程版本,线程安全,CopyOnWriteArrayList()方式 4.多线程版本,线程安全,Collections.synchr ...