你真的搞懂了Java中的<<、>>、>>>运算符嘛?
在搞懂<<、>>、>>>之前,我们需要先了解二进制中的源码、反码、补码...
二进制中的原码、反码、补码
有符号数:
对于有符号数而言,符号的正、负机器是无法识别的,但由于“正、负”恰好是两种截然不同的状态,如果用“0”表示“正”,用“1”表示“负”,这样符号也被数字化了,并且规定将它放在有效数字的前面,即组成了有符号数。所以,在二进制中使用最高位(第一位)来表示符号,最高位是0,表示正数;最高位是1,表示负数。
100000000000000001111100
无符号数:
无符号数是针对二进制来讲的,无符号数的表数范围是非负数。全部二进制均代表数值(所有位都用于表示数的大小),没有符号位。即第一个"0"或"1"不表示正负
000000000000000001111100
对于有符号数而言的性质:
(1)二进制的最高位是符号位:0表示正数,1表示负数
(2)正数的原码、反码、补码都一样
(3)负数的反码 = 它的原码符号位不变,其他位取反(0 ->1 ; 1->0 )
(4)负数的补码 = 它的反码 +1
(5)0的反码、补码都是0
(6)在计算机运算的时候,都是以补码的方式来运算的
有符号数运算案例
- 正数相加:
例如:1+1 ,在计算机中运算如下:
1的原码为: 00000000 00000000 00000000 00000001
反码: 00000000 00000000 00000000 00000001
补码: 00000000 00000000 00000000 00000001
两数的补码相加: 00000000 00000000 00000000 00000010( 转换为10进制) = 2
- 正数相减:
例如:1 - 2,在计算机中运算如下:
在计算机中减运算其实是作为加运算来操作的,所以,1-2 = 1 + ( -2 )
第一步:获取1的补码
00000000 00000000 00000000 00000001第二步:获取-2的补码
-2的原码:10000000 00000000 00000000 00000010
-2的反码:11111111 11111111 11111111 11111101
-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操作,在很多情况下可以当做乘2使用,但是并不代表真正的乘2,在一些特殊情况下并不等价
左移18位

此时二进制首位为1,此时数值为 -1058799616,同理,如果左位移20位,则值为 59768832 又变成了正数
注意:所以根据这个规则,如果任意一个十进制的数左位移32位,右边补位32个0,十进制岂不是都是0了?当然不是!!! 当int 类型的数据进行左移的时候,当左移的位数大于等于32位的时候,位数会先求余数,然后用该余数进行左移,也就是说,如果真的左移32位的时候,会先进行位数求余数,即为左移32位相当于左移0位 ,所以左移 33 的值和左移一位1 是一样的
>> 右移运算符
100 带符号右移
100 源码补码均为:00000000 00000000 00000000 01100100
右移四位: 00000000 00000000 00000000 00000110
结果为:6
-100 带符号右移
-100原码: 10000000 00000000 00000000 01100100
-100补码: 保证符号位不变,其余位置取反并加1
11111111 11111111 11111111 10011100
右移4位 : 在高位补1
11111111 11111111 11111111 11111001
补码形式的移位完成后,结果不是移位后的结果,还需要进行变换才行。其方法如下:
保留符号位,然后按位取反: 10000000 00000000 00000000 00000110
然后加1,即为所求数的原码: 10000000 00000000 00000000 00000111
结果为:-7
>>> 无符号右移运算符
无符号右移运算符和右移运算符是一样的,不过无符号右移运算符在右移的时候是补0的,而右移运算符是补符号位的
100 无符号右移 4 位
100 源码补码均为:00000000 00000000 00000000 01100100
右移四位: 00000000 00000000 00000000 00000110
结果为:6
-100无符号右移4位
-100原码: 10000000 00000000 00000000 01100100
-100补码: 保证符号位不变,其余位置取反并加1
11111111 11111111 11111111 10011100
无符号右移4位 : 在高位补0
00001111 11111111 11111111 11111001
结果为:268435449
总结:正数的左移与右移、无符号右移、负数的无符号右移,就是相应的补码移位所得,在高位补0即可
负数的右移,就是补码高位补1,然后按位取反加1即可
你真的搞懂了Java中的<<、>>、>>>运算符嘛?的更多相关文章
- 一文搞懂:java中的VO、PO、BO、DAO、POJO
针对java工程里的各种带O的对象,进行分析,了解各自的作用. PO:persistent object,持久对象.与数据库里表字段一一对应.PO是一些属性,以及set和get方法组成.一般情况下,一 ...
- 一文搞懂所有Java集合面试题
Java集合 刚刚经历过秋招,看了大量的面经,顺便将常见的Java集合常考知识点总结了一下,并根据被问到的频率大致做了一个标注.一颗星表示知识点需要了解,被问到的频率不高,面试时起码能说个差不多.两颗 ...
- 【JAVA零基础入门系列】Day5 Java中的运算符
运算符,顾名思义就是用于运算的符号,比如最简单的+-*/,这些运算符可以用来进行数学运算,举个最简单的栗子: 已知长方形的长为3cm,高为4cm,求长方形的面积. 好,我们先新建一个项目,命名为Rec ...
- Java 中的运算符和流程控制
Java 中的运算符和流程控制 + 面试题 算术运算符 Java 中的算术运算符,包括以下几种: **算术运算符** **名称** **举例** + 加法 1+2=3 - 减法 2-1=1 \* 乘法 ...
- Java中移位操作运算符的理解
java中的移位运算符有三种: 1. <<: 左移 2. >>: 右移 3. >>>: 无符号右移 使用方法:左移就是将左边的操作数在内存中的二进制数据左移指 ...
- JAVA_SE基础——11.Java中的运算符
在程序设计中,运算符应用得十分广泛,通过运算符可以将两个变量进行任意运算.数学中的"+"."-"."*"."/"运算符同 ...
- Java中位运算符的使用
先预知识: 数据在计算机中是以二进制的形式进行存储的,而二进制在内存中是以补码的形式进行存储的.在介绍位运算之前,首先来看一下原码.反码和补码的概念.由于正数的原码.反码和补码的形式都是一样的,所以以 ...
- Java中的运算符及表达式
常用的运算符:赋值运算符(=).加法运算符(+).乘法运算符(*).除法运算符(/).括号运算符(( )).余数运算符(%).布尔运算符. 注释符(//).注释的内容为双反斜杠后的内容至换行结束. j ...
- Java 中位移运算符 >>,>>>,<<
Java 中的三种位移运算符 java中有三种移位运算符 << : 左移运算符,num << 1,相当于num乘以2 >> : ...
随机推荐
- WPF Animation For SizeChanged Of UIElement
效果图 学到一个新词: Show me the money 背景 这几天查资料,看到 CodeProject 上面的一篇 Post <Advanced Custom TreeView Layou ...
- 关于TCP状态TIME_WAIT的理解
1.TIME_WAIT的作用: TIME_WAIT状态存在的理由:1)可靠地实现TCP全双工连接的终止 在进行关闭连接四次挥手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器 ...
- docker理论题-02
1.什么是namespace? 答:名称空间,作用隔离容器 2.namespace隔离有那些? 答:ipc:共享内存.消息队列 mnt:挂载点 net:网络栈 uts:域,主机名 user:用户,组 ...
- 1054D Changing Array 【位运算+思维】
题目:戳这里 题意:两个数n,k,满足给的n个数小于2的k次方.每个数可以进行一次操作,即把a[i]换成a[i]^(1<<k-1);求最多的连续区间数使得 区间[L,R] (1<=L ...
- vuepress & ReferenceError: window is not defined
vuepress & ReferenceError: window is not defined bug Client Compiled successfully in 15.35s Serv ...
- how to read the system information by using the node cli tool?
how to read the system information by using the node cli tool? node cli & get system info demos ...
- http cache & 浏览器缓存,存储位置的优先级,条件?
http cache & 浏览器缓存,存储位置的优先级,条件? memory cache disk cache 浏览器缓存,存储位置的优先级,条件, 机制,原理是什么? from memory ...
- dart 匹配基本数组
List<dynamic> evalList(String text) { var r = []; var i = 0; var isList = false; void parseSta ...
- Baccarat流动性挖矿的收益能否持续?该如何参与Baccarat流动性挖矿?
2020年DeFi市场火热,众多投资机构纷纷入场,分享这场资本盛宴.然而,目前市面上大多数DeFi项目手续费高昂,小资金的投资者无法入市.为了让更多的用户参与其中,NGK推出了Baccarat流动性挖 ...
- 纯js日历插件
成品的效果图 1.HTML文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...