1、        有符号数和无符号数

我们的实数分为正数和负数和0三部分

Byte数据类型一共有8位,如果是无符号数,最大可以表示的数为11111111 = 256 -1 = 255

无符号数代指不需要符号指明就可以知道它是什么数值大小。如果知道范围是正数和0的话,范围确实是0~255了

可是我们的byte除了存储正数、0还需要存储负数。因此需要一个位置装载符号位。因此我们留出一个位置装符号位,其他位置存储值。第一个位置为0代表正数,第一个数为1代表负数。也就是我们的原码。然后范围应该是-2^7-1 ~ 2^7-1

2、        引出补码的概念

按前面的方式,我们使用原码进行运算

正数运算:

00001001

+

01111101

= 10000110 第一位为符号位,所以值为 -6 计算用的是:9+125 = 134 超过了-127~127的范围丢失精度没问题。

换小一点的数值:

00001001

+

00000101

=   00001110  9 + 5 = 14  计算结果对应上去了

如果是减法运算呢?

00001001

+

10000101

= 10001110 = -14 这个减法当成加它的负数形式得到的有问题。我们除非让加负数的时候特殊处理,并不是做二进制加法运算才行。于是我们想办法。

我们知道一些现象:

把某物体左转 90 度,和右转 270 度,在不考虑圈数的条件下,最终的效果是相同的;

把分针倒拨 20 分钟,和正拨 40 分钟,在不考虑时针的条件下,效果也是相同的

把数字 87,减去 25,和加上 75,在不考虑百位数的条件下,效果也是相同的;

我们找它们的规律:

第一个要求两边组成1个圆

90+270 = 360

第二个要求总共60分钟,也是一个圆

20 + 40 = 60

第三个要求更难理解一些了,

62 和162 相等,等于每过100就重置,把它也想象成一个圆,加法走的也是环线

要求25 + 75 = 100

这里的100/360/60都是一个周期,我们把它叫做“模”(也可以理解成进制)。然后25 和75 这种就是在该进制中的互补的数。

数A + 数A的补数 = 进制

数B – 数A = 数B - (进制 – 数A的补数)

= 数B + 数A的补数  - 进制

=数B + 数A的补数  (因为数B和数A在同一进制下,所以-进制可以舍去)

我们去分析我们这里的问题了。

如果能找到byte运算的进制,是不是就可以求到对应的补码,将减法变成加法形式呢?

这个进制应该很好找:

数A + 数B = 100000000 也就是到了>100000000的数就会将前面的东西舍去了,值的范围只是 00000000这一块。这里要注意一些东西,也就是这是二进制而不是十进制。

进行与负数的加法也就是与该数对应绝对值整数的补数做加法,减的过程就是逆旋转的过程。

于是求负数的补数:

补数 = 100000000(2进制) - |负数的绝对值|

如: -5 的补数 = 256 – 5 = 251

100000000

-

000000101

011111011 (这里直接2进制减法相当于逆时针旋转)

8位也就是11111011

实验一次:

8-5 = 3

00001000

+

11111011

=

100000011 舍去逸出的位,得到:00000011 也就是3

得到补数的过程也就是我们的由原码得到反码的过程,不过符号位要忽略掉计算的时候。然后总结规律得出了一个反码的概念,得到了一个计算式:

反码 = 原码逐位取反,符号位不变

补码 = 反码 + 1

与正数的计算肯定用的不是它的补码而是原来的值,于是再得出结论:

正数的补码等于它的反码等于它的原码

由0值引出-128的由来:

我们都是原码表示的时候,可以发现0的位置可以是2个值:

00000000 和100000000 分别代表+0 和-0

但是我们将0都转换为补码形式发现:

100000000 – 0 = 100000000 。也就是说0的补码只有1种表示形态了,也就是00000000

那么我们的补码中将就多了1个位置出来,可以存储其他值。我们将10000000 如果是无符号数则为128,所以我们这里就多存储了一个负数-128

这里需要注意1个东西:

原码和反码这些都是虚拟存在的,它是在换算补码过程中的产物,所以我们不会去管-128如果换算成原码是不是成-0了,为了解决减法问题和0有两个位置的问题等我们才找到了补码这种存储方式的。

就是原和反的过程是过度的过程,计算机内计算和存储都是补码。补码的由来是负数在进制内相当于它的补数。正数的补码是它本身(不是补数)。求补码的过程和利用补码求10进制值可以用前人总结出的规律,但是要注意一些特殊值,所以理解根本上的求补是很有必要的。

这里引出前面讲的另一个误区:

我们前面理解的二进制形式是带符号的,符号是在二进制之外的东西,包括浮点数的小数点这些。

其实是有问题的,我们java中的二进制就已经存储了数据的全部信息,包括了整数与分数,包括了符号位。

这里可以发现一个问题:

数值的2进制形式表现的是它的补码形态,输出的二进制文件会将前面的0都省略

参考链接:https://blog.csdn.net/z69183787/article/details/79387207

https://blog.csdn.net/TSZ0000/article/details/82881888

https://blog.csdn.net/snowsnowsnow1991/article/details/47445153

补码的来源以及为什么byte的最小值是-128的更多相关文章

  1. java byte为何范围是-128~127

    从我们接触Java的时候,就被告知基础类型byte是一个字节,占8位,表示的范围是-128~127.那么为什么会这个范围呢?   咱们先回顾一下计算机基础: 1. 在计算机内部数据的存储和运算都采用二 ...

  2. mysql数据库TINYINT取值范围详解

    分享下mysql中TINYINT的取值范围,很基础的一些内容. 在MySQL的数据类型中,Tinyint的取值范围是:带符号的范围是-128到127.无符号的范围是0到255(见官方<MySQL ...

  3. Java 简介与安装、语法说明、数据类型

    目录 Java 介绍 Java 简介 Java 语言跨平台原理 JRE 和 JDK JDK 下载/安装说明 Java 语法说明 注释 关键字 标识符 数据类型 基本数据类型 引用数据类型 隐式类型转换 ...

  4. int的最大最小值补码原码转换

    原码 正数的二进制表示即为原码(正数的原码.反码.补码均一致) 补码 负数的补码为符号位不变,其余为取反,然后加1 补码的设计目的 (原因:带符号的数加减失效) 1.使符号位能够参与加减运算 2.将减 ...

  5. bit 和 byte

    bit bit是计算机的最小的存储单元,一切数据最终都以bit的形式存放在计算机之中. 一个bit有且只有两种状态.要么是0,要么是1.像这样: 多个bit组合在一起就可以构成更复杂的数据.例如,8个 ...

  6. java 变量及数据类型、原码、反码、补码

    Java基础——变量及数据类型 变量的概念 内存中的一个存储区域 变量名+数据类型 可在同一类型范围内不断变化 为什么定义变量: 用于不断的存放同一类型的常量,并可以重复使用 使用变量注意: 变量的作 ...

  7. Java中基本数据类型byte,short,char,int,long,float,double 取值范围

    部分内容转自:java 彻底理解 byte char short int float long double 首先说byte: 这段是摘自jdk中 Byte.java中的源代码: /** * A co ...

  8. byte & 0xff char 转换

    https://blog.csdn.net/lixingtao0520/article/details/75450883 版权声明:本文为博主原创文章,转载请注明作者与出处,http://blog.c ...

  9. java 彻底理解 byte char short int float long double

    遇到过很多关于 数值类型范围的问题了,在这做一个总结,我们可以从多方面理解不同数值类型的所能表示的数值范围 在这里我们只谈论 java中的数值类型 首先说byte: 这段是摘自jdk中 Byte.ja ...

随机推荐

  1. Tomcat的overview界面说明

    Tomcat的overview界面说明 一.Tomcat的overview界面 双击或者open,进入Tomcat的overview界面, 一般情况workspace的子路径为.metadata.pl ...

  2. 新建Maven项目建成后本应该有的src/main/java和src/test/java目录并没有出现:

    转自:http://www.cnblogs.com/dong-dong-dong/p/9565466.html 新建Maven项目建成后本应该有的src/main/java和src/test/java ...

  3. 【HBase调优】Hbase万亿级存储性能优化总结

    背景:HBase主集群在生产环境已稳定运行有1年半时间,最大的单表region数已达7200多个,每天新增入库量就有百亿条,对HBase的认识经历了懵懂到熟的过程.为了应对业务数据的压力,HBase入 ...

  4. Learning-Python【补充篇】:Python之可变类型与不可变类型

    可变类型 值变了,但是id没有变,证明没有生成新的值而是在改变原值,原值是可变类型 不可变类型 值变了,id也跟着变,证明是重新开辟一块内存空间生成了新的值,而不是在改变原值,原值是不可变类型

  5. 用python写MapReduce函数——以WordCount为例

    尽管Hadoop框架是用java写的,但是Hadoop程序不限于java,可以用python.C++.ruby等.本例子中直接用python写一个MapReduce实例,而不是用Jython把pyth ...

  6. 将nginx添加至service服务

    一.问题描述: 无法用service命令启动nginx 二.问题分析: /etc/init.d/目录下缺少nginx默认启动脚本 三.问题解决: 在/etc/init.d/路径下添加脚本文件,名称为n ...

  7. CSS 简介 4

    css css尺寸属性 height 设置元素的高度 line-height 设置行高 max-height 设置元素的最大高度 max-width 设置元素的最大宽度 min-height 设置元素 ...

  8. 微信小程序之 真机键盘弹窗遮盖input框

    正常效果: 问题效果: 发现这个问题后呢,我先去看了api,api上是这么说的 哦吼~ 然后我也不知道是不是我的打开方式不对还是什么~~ 没有效果~~  那怎么办呢~~  换方法呗~~ 我只好用这个方 ...

  9. react-native android 运行命令

    debug模式运行 sudo react-native run-android release模式运行 sudo react-native run-android --variant=release ...

  10. Spring中的@Async

    在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在spring 3.x之后, ...