二进制原码、反码、补码以及Java中的<< 和 >> 和 >>> 详细分析
1、计算机二进制系统中最小单位bit
在计算机二进制系统中:
bit (位) :数据存储的最小单元。 简记为b
,也称为比特(bit
),每个二进制数字0或1就是一个位(bit
),其中,每8bit = 1 byte
(字节);
再回顾Java 中的数据类型,如int数据类型 = 4个byte(字节)
,而1 byte(字节) = 8 bit(位)
;也就我们常说的int = 32位
(说白了,在二进制系统中是以bit 作为数据存储单元的)。如下
2、有符号数和无符号数
有符号数和无符号数简单的说就是分别对应正数和负数,在二进制系统中是以bit(位)来作为数据存储单元的,最高位(第一位)是符号位,正数符号位为“0” ,负数符号位为“1” 。
例子:
假设 int number = 1
,那么number在计算机系统中将表示如下:
00000000 00000000 00000000 00000001
同理可得,number = -1
时,在二进制中表示如下:
10000000 00000000 00000000 00000001
注意:最高位(第一位)是符号位,因为是number值为1是一个正数,所以最高位为0;
3、二进制的原码、反码、补码
原码
原码就是机器数,是加了一位符号位的二进制数(因为数值有正负之分),正数符号位为0,负数符号位为1。
反码
带符号位的原码乘除运算时结果正确,而在加减运算的时候就出现了问题,比如: 用十进制表示:1 + (-1) = 0
, 但用二进制表示:
00000001 + 10000001 = 10000010,
将结果换算成十进制数也就是 -2。于是在原码的基础上发明了反码,用来解决这种问题。
补码
虽然反码的出现解决了正负数的加减问题, 但却让0这个数字有了两种"形态": "0"和"-0", 但这是不合逻辑的,只应该有一个0,所以出现了补码。
对于有符号数而言:
1、正数的原码、反码、补码都一样;
2、负数的反码 = 它的原码符号位不变,其他位取反(取反的意思:0 换成 1 、 1 换成 0 );
3、负数的补码 = 它的反码 +1;
4、0的反码、补码都是0;
【特别注意】
1、在计算机运算的时候,都是以 补码 的方式来运算的 。
2、二进制 转为 十进制,必须使用 二进制 的原码进行转换 。
例子:
下面我们就使用“有符号数”来模拟一下,在计算机中是怎样运算的。
(1)正数相加:
例如:1+1 ,在计算机中运算如下:
1的原码为:
00000000 00000000 00000000 00000001
因为“正数的原码、反码、补码都一样”,所以,1的补码 = 1的原码,所以 1的补码+ 1的补码 就等于:
00000000 00000000 00000000 00000001
- 00000000 00000000 00000000 00000001
=
00000000 00000000 00000000 00000010
00000000 00000000 00000000 00000010( 转换为10进制) = 2
(2)正数相减:
例如:1 - 2,在计算机中运算如下:
在计算机中减运算其实是作为加运算来操作的,所以,1 - 2 = 1 + ( -2 )
第一步:把 1的补码找出来(因为正数的原码、反码、补码都一样,所以我们可通过原码直接获取补码):
1的补码:
00000000 00000000 00000000 00000001
第二步:把-2的原码找出来:
-2的原码:
10000000 00000000 00000000 00000010
第三步:把-2的反码找出来:
-2的反码:
11111111 11111111 11111111 11111101
第三步:把-2的补码找出来:
-2的补码:
11111111 11111111 11111111 11111110
第四步:1的补码与-2的补码相加:
00000000 00000000 00000000 00000001
- 11111111 11111111 11111111 11111110
=
11111111 11111111 11111111 11111111
第五步:将计算结果的补码转换为原码,反其道而行之即可(如果想将二进制转换为十进制,必须得到二进制的原码)
补码:11111111 11111111 11111111 11111111
=
反码:11111111 11111111 11111111 11111110
=
原码:10000000 00000000 00000000 00000001
第六步:将计算结果的二进制原码 转换 为十进制
二进制原码:10000000 00000000 00000000 00000001 = 1*2^0 = -1
4、思考:java中为什么byte的取值范围是-128~127
java中byte占一个字节, 也就是8bit(位), 其中最高位是符号位, 剩下7位用来表示数值.若符号位为0, 则表示为正数,范围为00000000~01111111(补码形式),也就是十进制的0-127. 若符号位为1, 则表示为负数, 范围为10000000~11111111(补码形式), -128~-1, 11111111转换为原码就是10000001,也就是-1。
在补码中,为了避免存在"-0",规定10000000为-128, 所以解释了byte的取值范围为什么是-128~127.
5、Java中的<< 和 >> 和 >>>
首先<< 和 >> 和 >>>是java中的位运算符,是针对二进制进行操作的。除了这些还有&、|、^、~、几个位操作符。不管是初始值是依照何种进制,都会换算成二进制进行位操作。这里主要讲解Java中的<< 和 >> 和 >>>。
<< 表示左移移,不分正负数,低位补0
注:以下数据类型默认为byte为8位,左移时不管正负,低位补0
正数:r = 20 << 2
20的二进制补码:0001 0100
向左移动两位后:0101 0000
结果:r = 80
负数:r = -20 << 2
-20 的二进制原码 :1001 0100
-20 的二进制反码 :1110 1011
-20 的二进制补码 :1110 1100
左移两位后的补码:1011 0000
反码:1010 1111
原码:1101 0000
结果:r = -80
‘ >> ’表示右移,如果该数为正,则高位补0,若为负数,则高位补1;
注:以下数据类型默认为byte为8位
正数:r = 20 >> 2
20的二进制补码:0001 0100
向右移动两位后:0000 0101
结果:r = 5
负数:r = -20 >> 2
-20 的二进制原码 :1001 0100
-20 的二进制反码 :1110 1011
-20 的二进制补码 :1110 1100
右移两位后的补码:1111 1011
反码:1111 1010
原码:1000 0101
结果:r = -5
‘ >>> ’ 表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0
注:以下数据类型默认为int 32位
正数: r = 20 >>> 2
的结果与 r = 20 >> 2 相同;
负数: r = -20 >>> 2
-20原码:10000000 00000000 00000000 00010100
反码:11111111 11111111 11111111 11101011
补码:11111111 11111111 11111111 11101100
右移:00111111 11111111 11111111 11111011
结果:r = 1073741819
最后,若有不足或者不正之处,欢迎指正批评,感激不尽!
欢迎各位关注我的公众号,里面有一些java学习资料和一大波java电子书籍,比如说周志明老师的深入java虚拟机、java编程思想、核心技术卷、大话设计模式、java并发编程实战.....都是java的圣经,不说了快上Tomcat车,咋们走!最主要的是一起探讨技术,向往技术,追求技术,说好了来了就是盆友喔...
参考:
https://www.cnblogs.com/summerdata/p/10722359.html
https://www.cnblogs.com/chuijingjing/p/9405598.html
二进制原码、反码、补码以及Java中的<< 和 >> 和 >>> 详细分析的更多相关文章
- JAVA:二进制(原码 反码 补码),位运算,移位运算,约瑟夫问题(5)
一.二进制,位运算,移位运算 1.二进制 对于原码, 反码, 补码而言, 需要注意以下几点: (1).Java中没有无符号数, 换言之, Java中的数都是有符号的; (2).二进制的最高位是符号位, ...
- Java学习第五篇:二进制(原码 反码 补码),位运算,移位运算,约瑟夫问题
一.二进制,位运算,移位运算 1.二进制 对于原码, 反码, 补码而言, 需要注意以下几点: (1).Java中没有无符号数, 换言之, Java中的数都是有符号的; (2).二进制的最高位是符号位, ...
- 位移&二进制转换&原码&反码&补码
<< 左移 按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零. 格式 需要移位的数字 << 移位的次数 计算过程 1. 按二进制形式把所有的数字向左 ...
- java原码反码补码以及位运算
原码, 反码, 补码的基础概念和计算方法. 对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式. 1. 原码 原码就是符号位加上真值的绝对值, 即 ...
- Java基础-原码反码补码
Java基础-原码反码补码 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 注意,我们这里举列的原码和反码只是为了求负数的补码,在计算机中没有原码,反码的存在,只有补码. 一.原码 ...
- Java 原码 反码 补码
本篇文章讲解了计算机的原码, 反码和补码. 并且进行了深入探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用反码, 补码的加法计算原码的减法. 论证部分如有不对的地方请各位牛人帮忙指正! 希 ...
- java基础知识-原码,反码,补码
1.正数:原码,反码,补码:都一样. 2.负数:和正数的储存方式不同,负数都是以补码形式存储的. <1>负数的补码 把负数的原码除了符号位取反后再+1. <2>负数的原码 把对 ...
- 原码 & 反码 & 补码 & 详解
本篇文章讲解了计算机的原码, 反码和补码. 并且进行了深入探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用反码, 补码的加法计算原码的减法. 论证部分如有不对的地方请各位牛人帮忙指正! 希 ...
- C语言原码反码补码与位运算.
目录: 一.机器数和真值 二.原码,反码和补码的基础概念 三.为什么要使用原码,反码和补码 四.原码,补码,反码再深入 五.数据溢出测试 六.位运算 ...
随机推荐
- 2019-2020-1 20199324《Linux内核原理与分析》第一周作业
1.问题:使用banner输出图形字符为什么都是大写? 2.实验二:基本概念及操作 作业:命令toilet和figlet的使用 使用如下命令安装 $ sudo apt-get update $ sud ...
- 四剑客(awk)
AWK AWK简介 虽然sed编辑器是非常方便自动修改文本文件的工具,但其也有自身的限制.通常你需要一个用来处理文件中的数据的更高级工具,它能提供一个类编程环境来修改和重新组织文件中的数据.这正是ga ...
- transcription-coupled repair|Germ|HK|TS|Mutation|四类变异
生命组学-可遗传变异 GC content:碱基: GC content不同的植物对应的gene length,可看作上图的转置: 由GC content看出来碱基变异程度,可以找到对应碱基改变,所以 ...
- SwipeRefreshLayout 下拉刷新
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com ...
- python3下scrapy爬虫(第十四卷:scrapy+scrapy_redis+scrapyd打造分布式爬虫之执行)
现在我们现在一个分机上引入一个SCRAPY的爬虫项目,要求数据存储在MONGODB中 现在我们需要在SETTING.PY设置我们的爬虫文件 再添加PIPELINE 注释掉的原因是爬虫执行完后,和本地存 ...
- ef codefirst VS里修改数据表结构后更新到数据库
2.根据已建立table的数据库建立ADO.NET数据模型在修改表后进入 工具->nuget包管理器->程序包管理器控制台 输入 enable-migrations 后vs会添加一个 ...
- iOS漂亮的Toolbar动画、仿美团主页、简易笔记本、流失布局、标签分组等源码
iOS精选源码 JPLiquidLayout 简单易用的流式布局 labelGroupAndStreamSwift---标签分组,单选,多选 iOS采用UITableView和UIScrollView ...
- E. Tree Painting(树形换根dp)
http://codeforces.com/contest/1187/problem/E 分析:问得分最高,实际上就是问以哪个节点出发得到的分数最多,而呈现成代码形式就变成了换根,max其得分!!!而 ...
- XiaoXiao
最开始认识孙亚龙因为他是we的对手,反向大招的琴女,被冯卓君按在地上摩擦.凭借规则优势去了上海全明星,在红方下外塔和蓝方上二塔那两次q,是他的游戏巅峰.之后他退出了游戏没有再重连,不卖肉松饼是一个承诺 ...
- Trie图 模板
trie图实际上是优化的一种AC自动机. trie图是在trie树上加一些失配指针,实际上是类似KMP的一种字符串匹配算法. 失配指针类似KMP的nx数组,有效地利用了之前失配的信息,优化了时间复杂度 ...