最近感觉自己的Java基础掌握的还不是很好,所以回头再来复习一下,顺便记录下我学习的笔记吧。
大家都知道,在计算机内部数据都是以二进制形式存在的。而二进制在计算机内部又有多种编码方式:
1、原码 如:3: 0000 0011 :第一位是符号位,0正,1负
2、反码 正数的反码和原码一样,负数的反码,保留符号位,其余按位取反。
如: -3:1000 0011 (原码)-----> 1111 1100(反码)
3、补码 (用的最多)正数的反码、补码和原码都一样。负数的补码=反码+1。
负数的原码 = 负数的补码 - 1 再取反 或 负数的原码 = 负数的补码取反 + 1;
如: -3:1000 0011 (原码)-----> 1111 1100(反码) ----->1111 1101(补码)
而在计算及内部对二进制进行运算用的是补码。
了解了以上知识,我们就可以学习位运算了,首先看图:

举例说明:
int num1 = 128;
int num2 = 128;
iny num3 = num1&num2;(与)
iny num4 = num1|num2;(或)
iny num5 = num1^num2;(异或)
iny num6 = ~ num1;(非)
/*
//正数的补码跟原码一样
0000 0000 0000 0000 0000 0000 1000 0000 (补)//128
0000 0000 0000 0000 0000 0000 1000 0001 (补)//129
----------------------------------------------------------
0000 0000 0000 0000 0000 0000 1000 0000(补)//128&129
只有两个位数都是1 才返回1 所以128&129 = 128
只要两个位数有一个是1 就返回1 所以128|129 = 129
0000 0000 0000 0000 0000 0000 1000 0001(补)//128|129
只要两个数相异则返回1,相同则返回0 128^129 = 1
0000 0000 0000 0000 0000 0000 0000 0001(补)
每一个位都取反 ~128 = -129
0000 0000 0000 0000 0000 0000 1000 0000 (补)//128
1111 1111 1111 1111 1111 1111 0111 1111(补)//~128
----------------------------------------------------
1000 0000 0000 0000 0000 0000 1000 0001 (负数的原码)//~128 = -129
*/
通过上面的计算我们得出:
num3 = 128;
num4 = 129;
num5 = 1;
num6 = -129;
左移:右边补0
int num7 = 2<<3;
0000 0000 0000 0000 0000 0000 0000 0010(补) //2
------------------------------------------------------------
0000 0000 0000 0000 0000 0000 0001 0000// 2<<3 = 16 =2*(2的3次方);
num7 = 16
int num8 = -2<<3;
1000 0000 0000 0000 0000 0000 0000 0010(原) //-2
------------------------------------------------------------
1111 1111 1111 1111 1111 1111 1111 1110(补)//-2
------------------------------------------------------------
1111 1111 1111 1111 1111 1111 1111 0000(补)//-2<<3
------------------------------------------------------------
1000 0000 0000 0000 0000 0000 0001 0000(原)//-2<<3 = -16=-2*(2的3次方);
num8 = -16;
右移:右边去掉3位,正数:左边添加3位0,负数左边添加3位1
int num9 = 16>>3
0000 0000 0000 0000 0000 0000 0001 0000//16
---------------------------------------------------------
0000 0000 0000 0000 0000 0000 0000 0010//16>>3 = 2 16/(2的3次方)
num9 = 2;
int num10 = -16>>3;
1000 0000 0000 0000 0000 0000 0001 0000(原)//-16
--------------------------------------------------------------
1111 1111 1111 1111 1111 1111 1111 0000(补)
1111 1111 1111 1111 1111 1111 1111 1110(补)//-16>>3
--------------------------------------------------------------
1000 0000 0000 0000 0000 0000 0000 0010(原)//-16>>3 = -2 -16/(2的3次方)
num10 = -2;
//无符号右移
int num11 = -16>>>3;
不管是正数还是负数,右边取出3位后,左边都补0
1000 0000 0000 0000 0000 0000 0001 0000(原)//-16
--------------------------------------------------------------
1111 1111 1111 1111 1111 1111 1111 0000(补)
0001 1111 1111 1111 1111 1111 1111 1110(补)//-16>>>3
--------------------------------------------------------------
正数原码补码一样 ----> -16>>>3 = 536870910
num11 = 536870910
在平时的运算当中,当搞不清楚运算符的优先级时,多加“()”将优先运算的用括号包起来。
网友评论