彻底搞懂Java中的>>,<<,>>>

前言

首先需要知道在Java基本数据类型中不存在无符号数,即全为有符号数,>>,<<,>>>分别表示算术右移,算术左移,逻辑右移(无符号右移) 对于了解原码,反码,补码的读者可以直接跳过“有符号数的表示”部分

有符号数的表示(补充了解)

1.原码

最左边一位二进制表示这个数的符号: ”0“代表正,”1“代表负。后面是它的”有效数字“。

一个字节存储的有符号数原码,有127个正数;有127个负数和2个”0“。

‘正’0:0 000 0000;‘负’0:1 000 0000;

2. 反码

用最高位‘0’表示符号为正,‘1’表示符号为负。符号位之后的二进制位用来存储这个数的有效数字:正数的有效数字不变,负数的有效数字取反。

1字节存储有符号数反码,有127个正数,127个负数和2个“0”,

“正”0:0 000 0000, “负”0:1 111 1111.

3. 补码

补码表示法仍然用最高有效位(MSB)表示一个有符号数的符号,“1”表示符号为负,“0”表示符号为正。

其他二进制位数用来存储这个数的有效数字。正数的有效数字不变,负数的有效数字取反后最低位加1.

算术右移,算术左移,逻辑右移

1. 总述

1
2
3
>>   :  算术右移,num >> 1,低位溢出,高位补符号位,在十进制数值上相当于num除以2
<< : 算术左移,num << 1,高位溢出,低位补0,在十进制数值上相当于num乘以2
>>> : 逻辑右移,忽略符号位,空位都以0补齐

2.逻辑右移详解

我们知道在Java中Integer占用4个字节,32位,最高位为符号位。Java中的数值用补码表示。 #### 正数 根据上节知识可知,正数的补码等于原码,此处以10为例。

1
2
3
4
10在Java中的二进制表示为:0000 0000 0000 1010
现在进行逻辑右移: 10>>>2
逻辑右移后的二进制表示为: 00 0000 0000 0010 (未补齐)
逻辑右移后的二进制表示为: 0000 0000 0000 0010 (0补齐)

负数

此处以-10为例。

1
2
3
4
-10在java中的二进制表示为:1111 1111 1111 0110
现在进行逻辑右移:-10>>>2
逻辑右移后的二进制表示为: 11 1111 1111 1101 (未补齐)
逻辑右移后的二进制表示为: 0011 1111 1111 1101 (0补齐)

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package test;

public class test {

public static void main(String[] args){
int num = -10;

//本身二进制结果
printInfo(num);

//右移2位后二进制结果
printInfo(num>>2);
System.out.println(num>>2);

//左移1位后二进制结果
printInfo(num<<2);
System.out.println(num<<2);

//逻辑右移(无符号右移)1位后二进制结果
printInfo(num>>>2);
System.out.println(num>>>2);
}

//转二进制
private static void printInfo(int num){
System.out.println(Integer.toBinaryString(num));
}
}

读者可以自行修改测试。


彻底搞懂Java中的>>,<<,>>>
https://hwh-2019.github.io/2022/11/18/彻底搞懂Java中的>>-<<->>>/
作者
HWH
发布于
2022年11月18日
许可协议