1.1、真值、机器数(原码、反码和补码)
真值:就是现实世界的值
机器数:计算机世界中的数字,原码、反码和补码都是机器数的一种
原码:真值变为原码就是,首位表示正负,0为正,1为负,值的部分变为二进制
反码:正数的反码是其本身,负数的反码是除符号位外其他位取反(0变为1,1变为0),正负真值的反码求和为11111111,但是原码没有这个规律
补码:正负真值的反码求和是11111111,但是不是0啊,所以规定负数的补码是反码加1,那么正负真值的补码求和就是(1)0000000,最高位会被舍去哦。
正数和+0的原码、反码、补码都是一样的。负数和-0的反码是其原码的符号位外其他位取反(0变为1,1变为0)
Java 中数字的计算是基于补码的,int类型就是32位补码。
查看 32位二进制补码 小工具
//Java Integer.toBinaryString 打印字符串,二进制补码默认为 32位,如果数字为负数则正好打印32位,如果为正数,则会以第一个1开始打印,如果为0就是0
//所以这里提供一个小工具方法,可以统一将二进制32位补码打印出来
public static String fullLengthTo32(int arg) {
String str = Integer.toBinaryString(arg);
int gap = 32 - str.length();
StringBuilder result = new StringBuilder();
for (int i = 0; i < gap; i++) {
result.append("0");
}
return result.append(str).toString();
}
1.2、与(&)、或(|)、异或(^)、非(~)运算
与、或、异或和非运算 都是基于二进制进行运算
Java中 int 类型基于 2 机制 32位补码
类型 | 举例 | 含义 |
---|---|---|
与运算 | A&B | 末位对齐,都为1得1,否则得0,与1111与运算,可以保留4位,&运算可用于截位 |
或运算 | A|B | 末位对齐,只要有一个为1即为1 |
异或运算 | A^b | 末位对齐,相同得0,不同得1 |
非运算 | ~A | 单值,全部取反,如果是机器数则可得补码(Java用补码表示机器数,且补码是2进制) |
异或运算的规律
1.a ^ a = 0
2. a^b = b ^a
3. a ^b ^ c = a ^ (b ^ c) = (a ^ b) ^ c;
4. d = a ^ b ^ c 可以推出 a = d ^ b ^ c.
5. a ^ b ^ a = b.
6.若x是二进制数0101,y是二进制数1011,则x^y=1110
1.3、位移运算 <<、>>和>>>
正数左位移n位相当于真值乘以2的n次幂,整体左移n位,高位舍弃n位,右边补n个0
正数右位移n位相当于真值除以2的n次幂,整体右移n位,末尾舍弃n位,左边补n个0
负数左移n位无法使用乘除描述,整体左移n位,高位舍去n位,低位补n个0
负数右移n位无法使用乘除描述,整体右移n位,低位舍去n位,高位补n个1
无符号右移n位无法使用乘除描述,整体右移n位,低位舍去n位,高位补n个零,无符号就是高位一致补零
1<<1:1左位移一位得 2:2正数左位移1位相当于真值乘以2的一次幂,整体左移,高位舍弃,右边补0
2>>1:2右位移一位得 1:1正数右位移1位相当于真值除以2的一次幂,整体右移,末尾舍弃,左边补0
(-1)<<1:-1左位移一位得 -2:-2负数左移1位无法使用乘除描述,整体左移,高位舍去,低位补0
(-1)>>1:-1右位移一位得 -1:-1负数右移1位无法使用乘除描述,整体右移,低位舍去,高位补1
(-1)>>>1:-1无符号右位移一位得 -1:2147483647无符号右移1位无法使用乘除描述,整体右移,低位舍去,高位补0,无符号就是高位补零的无符号