星星之火-JAVA中的>>>与>>区别

本文最后更新于:December 3, 2021 pm

积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里,不积小流无以成江海。齐骥一跃,不能十步,驽马十驾,功不在舍。面对悬崖峭壁,一百年也看不出一条裂缝来,但用斧凿,能进一寸进一寸,能进一尺进一尺,不断积累,飞跃必来,突破随之。

目录

1.预备知识

计算机中整数的存储形式:在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理,加法和减法也可以统一处理。「正数的补码等于原码;负数的补码等于反码加1,而反码等于原码符号位不变,其余各位取反」(符号位不反!!!)

负数在计算机中以补码的形式存储,正数在计算机中以原码的形式存储。

二进制最左端的数字为符号位,0代表正,1代表负。

注意:没有<<<运算符!!因为左移都是补零,没有正负数的区别。

<< 、>> 为算术运算符;>>> 为逻辑运算符。>>(带符号右移) 和 >>>(无符号右移) 。

其中,>>> 表示不带符号向右移动二进制数,移动后前面统统补0; >> 表示带符号移动。

都可以理解成是在补码的形式上进行移动的!!。

>>>只是java中的!!!

负数求补码

如下步骤:
1、首先求出负数的原码,如-8的原码为 1000 1000,
2、通过原码求出它的反码,负数的反码就是 除符号为以外,其余的全部求反,如-8 反码为 1111 0111,
3、负数的补码 +1,就是它的补码,如 -8 的补码为 1111 1000

简单说就是:负数的补码是在原码的基础上除符号位外其余位取反后+1。
也可以是:先写出负数的相反数的原码,再将最高位变1(已经是1了就不管了),再将除符号位外的其他位取反+1。

2.示例

以-12为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        System.out.println("=====================================");
System.out.println(Integer.toBinaryString(12));
System.out.println(Integer.toBinaryString(-12));
System.out.println(Integer.toBinaryString(-12>>3));
System.out.println(-12>>3);
System.out.println(Integer.toBinaryString(-12>>>3));
System.out.println(-12>>>3);
// 00000000000000000000000000001100 12原码
// 11111111111111111111111111110011 反码
// 11111111111111111111111111110100 补码

//输出
========================================
00000000000000000000000000001100 //12
11111111111111111111111111110100 // -12
11111111111111111111111111111110 // -2,用>>移动后用的1在左边进行补充
-2
11111111111111111111111111110 // 536870910,用>>>移动后用的0在左边进行补充,完整见下
/*
00011111111111111111111111111110
*/
536870910

可以看见,是 >> 运算符时,左边添加的是符号位1;如果是正数,添加的就是0;而是 >>> 运算符时,没有管符号位,是直接左边添加的0。

再如:

如 -12 的二进制为:1111 1111 1111 1111 1111 1111 1111 0100;

-12 >> 3 即带符号右移3位,结果是:1111 1111 1111 1111 1111 1111 1111 1110,十进制为: -2;

-12 >>> 3 就是右移三位,前面补零,为:0001 1111 1111 1111 1111 1111 1111 1110,十进制为:536870910。

最后再加一个对照示例:

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
System.out.println(Integer.toBinaryString(12));
System.out.println(Integer.toBinaryString(12>>3));
System.out.println(Integer.toBinaryString(12>>>3));
System.out.println("==========================================");
System.out.println(Integer.toBinaryString(-12));
System.out.println(Integer.toBinaryString(-12>>3));
System.out.println(Integer.toBinaryString(-12>>>3));

//输出
1100
1
1
==========================================
11111111111111111111111111110100
11111111111111111111111111111110
11111111111111111111111111110


//将他们格式化一下
00000000000000000000000000001100 //12
00000000000000000000000000000001 //1
00000000000000000000000000000001 //1
==========================================
11111111111111111111111111110100 //-12
11111111111111111111111111111110 //左边补充的1
00011111111111111111111111111110 //左边补充的0

这下应该清除了。>>移动的时候是用的符号位的数进行补充,而>>>是直接补充的0。