Open BruceOuyang opened 2 years ago
示例代码
/**
* @ClassName: BitOperationTest
*
* @Description: 位运算测试
*
* @Author: bruce.ouyang
* @Date: 2022/5/3 上午10:57
* @Version: v1.0
*/
public class BitOperationTest {
public static void main(String[] args) {
System.out.println("对于所有的位运算,操作的都是二进制的数据,如果数据为其他进制,会先转换为二进制再做计算");
System.out.println("一个整型数据占 4 字节,每个字节占 8 位,等于一个整型数据占 32 位");
System.out.println("低精度的 byte / short 不适合做位运算,会有溢出,一般位运算基础类型为 int / long");
System.out.println("");
bitLogicOpTest();
bitMoveOpTest();
limitMoveBitTest();
basicTypeBitTest();
// checkMoveBitTest();
}
/**
* 位逻辑运算
* & 与 a & b
* | 或 a | b
* ~ 取反 ~a
* ^ 异或 a ^ b
*/
public static void bitLogicOpTest() {
System.out.println("=========================================================");
System.out.println("= 位逻辑运算");
System.out.println("=========================================================");
System.out.println("");
System.out.println("- 与运算: a & b");
System.out.println("");
System.out.println("与运算,对应位都为 1,结果为 1,否则为 0");
System.out.println("相当于一般逻辑运算符 and ,把 1 视为 true, 把 0 视为 false");
System.out.println("");
System.out.println("12 & 8 = " + (12 & 8));
System.out.println("");
System.out.println(" 0000 0000 0000 0000 0000 0000 0000 1100 -> 十进制 12 的二进制形式");
System.out.println(" & 0000 0000 0000 0000 0000 0000 0000 1000 -> 十进制 8 的二进制形式");
System.out.println("———————————————————————————————————————————————");
System.out.println(" 0000 0000 0000 0000 0000 0000 0000 1000");
System.out.println("");
System.out.println("- 或运算: a | b");
System.out.println("");
System.out.println("或运算,对应位含有 1,结果为 1,否则为 0");
System.out.println("相当于一般逻辑运算符 or ,把 1 视为 true, 把 0 视为 false");
System.out.println("");
System.out.println("12 | 8 = " + (12 | 8));
System.out.println("");
System.out.println(" 0000 0000 0000 0000 0000 0000 0000 1100 -> 十进制 12 的二进制形式");
System.out.println(" | 0000 0000 0000 0000 0000 0000 0000 1000 -> 十进制 8 的二进制形式");
System.out.println("———————————————————————————————————————————————");
System.out.println(" 0000 0000 0000 0000 0000 0000 0000 1100");
System.out.println("");
System.out.println("- 取反运算: ~a");
System.out.println("");
System.out.println("取反运算,对应位为 1,结果为 0,否则为 1");
System.out.println("相当于一般逻辑运算符 ! ,把 1 视为 true, 把 0 视为 false");
System.out.println("");
System.out.println("~12 = " + (~12));
System.out.println("");
System.out.println(" ~ 0000 0000 0000 0000 0000 0000 0000 1100 -> 十进制 12 的二进制形式");
System.out.println("———————————————————————————————————————————————");
System.out.println(" 1111 1111 1111 1111 1111 1111 1111 0011");
System.out.println("");
System.out.println("- 异或运算: a ^ b");
System.out.println("");
System.out.println("异或运算,对应位值相同,结果为 0,否则为 1");
System.out.println("相当于一般逻辑运算符 equals ,把 1 视为 true, 把 0 视为 false");
System.out.println("");
System.out.println("12 ^ 8 = " + (12 ^ 8));
System.out.println("");
System.out.println(" 0000 0000 0000 0000 0000 0000 0000 1100 -> 十进制 12 的二进制形式");
System.out.println(" ^ 0000 0000 0000 0000 0000 0000 0000 1000 -> 十进制 8 的二进制形式");
System.out.println("———————————————————————————————————————————————");
System.out.println(" 0000 0000 0000 0000 0000 0000 0000 0100");
System.out.println("");
}
/**
* 位移运算
* << 左移 a << 2
* >> 右移 a >> 4
* >>> 无符号右移 a >>> 2
*/
public static void bitMoveOpTest() {
System.out.println("=========================================================");
System.out.println("= 位移运算");
System.out.println("=========================================================");
System.out.println("");
System.out.println("- 左移运算: a << n");
System.out.println("");
System.out.println("左移运算,对应位整体向左移动 n 位,低位补 0, 高位溢出的舍去");
System.out.println("相当于乘以 2 的 n 次方");
System.out.println("");
System.out.println("12 << 2 = " + (12 << 2));
System.out.println("");
System.out.println(" << 2 0000 0000 0000 0000 0000 0000 0000 1100 -> 十进制 12 的二进制形式");
System.out.println("———————————————————————————————————————————————————————");
System.out.println(" 0000 0000 0000 0000 0000 0000 0011 0000");
System.out.println("");
System.out.println("");
System.out.println("- 右移运算: a >> n");
System.out.println("");
System.out.println("正数右移运算,对应位整体向右移动 n 位,高位补 0, 低位溢出的舍去");
System.out.println("相当于除以 2 的 n 次方");
System.out.println("");
System.out.println("12 >> 2 = " + (12 >> 2));
System.out.println("");
System.out.println(" >> 2 0000 0000 0000 0000 0000 0000 0000 1100 -> 十进制 12 的二进制形式");
System.out.println("———————————————————————————————————————————————————————");
System.out.println(" 0000 0000 0000 0000 0000 0000 0000 0011");
System.out.println("");
System.out.println("负数右移运算,对应位整体向右移动 n 位,高位补 1, 低位溢出的舍去");
System.out.println("");
System.out.println("-12 >> 2 = " + (-12 >> 2));
System.out.println("");
System.out.println(" >> 2 1111 1111 1111 1111 1111 1111 1111 0011 -> 十进制 -12 的二进制形式");
System.out.println("———————————————————————————————————————————————————————");
System.out.println(" 1111 1111 1111 1111 1111 1111 1111 1100");
System.out.println("");
System.out.println("");
System.out.println("- 无符号右移运算: a >>> n");
System.out.println("");
System.out.println("无符号右移运算,对应位整体向右移动 n 位,高位补 0, 低位溢出的舍去");
System.out.println("相当于除以 2 的 n 次方");
System.out.println("");
System.out.println("12 >>> 2 = " + (12 >>> 2));
System.out.println("");
System.out.println(" >>> 2 0000 0000 0000 0000 0000 0000 0000 1100 -> 十进制 12 的二进制形式");
System.out.println("———————————————————————————————————————————————————————");
System.out.println(" 0000 0000 0000 0000 0000 0000 0000 0011");
System.out.println("");
System.out.println("");
System.out.println("-12 >>> 2 = " + (-12 >>> 2));
System.out.println("");
System.out.println(" >>> 2 1111 1111 1111 1111 1111 1111 1111 0011 -> 十进制 -12 的二进制形式");
System.out.println("———————————————————————————————————————————————————————");
System.out.println(" 0011 1111 1111 1111 1111 1111 1111 1100");
System.out.println("");
}
public static void limitMoveBitTest() {
System.out.println("=========================================================");
System.out.println("= 极端位移测试");
System.out.println("=========================================================");
System.out.println("");
System.out.println("- 左移运算: a << n, n > 32");
System.out.println("");
System.out.println("左移运算,对应位整体向左移动 n 位,低位补 0, 高位溢出的舍去");
System.out.println("若 n > 32, 相当于乘以 2 的 n % 32 次方");
System.out.println("");
System.out.println("12 << 27 = " + (12 << 27));
System.out.println("12 << 30 = " + (12 << 30));
System.out.println("12 << 32 = " + (12 << 32));
System.out.println("12 << 33 = " + (12 << 33));
System.out.println("12 << 64 = " + (12 << 64));
System.out.println("12 << 96 = " + (12 << 96));
System.out.println(" 0000 0000 0000 0000 0000 0000 0000 1100 -> 十进制 12 的二进制形式");
System.out.println("");
}
public static void basicTypeBitTest() {
System.out.println("=========================================================");
System.out.println("= 低精度整型位移运算");
System.out.println("=========================================================");
System.out.println("");
byte a = (byte) (-32 >>> 1);
System.out.println("byte -32 >>> 1 = " + a);
short b = (short) (-128 >>> 1);
System.out.println("short -128 >>> 1 = " + b);
System.out.println("");
System.out.println("低精度整形是不适合做位移操作的,会有溢出");
}
private static void checkMoveBitTest() {
int a = 12;
int count = 10;
int v = a << count;
int v_dynamic = v;
int calc_count = 0;
while((v_dynamic = v_dynamic >> 1) > 0) {
calc_count ++;
if (v_dynamic == a) {
break;
}
}
System.out.println(calc_count == count);
}
}
零、基本数据类型
一、位逻辑运算
与运算,对应位都为 1,结果为 1,否则为 0 相当于一般逻辑运算符 and ,把 1 视为 true, 把 0 视为 false
或运算,对应位含有 1,结果为 1,否则为 0 相当于一般逻辑运算符 or ,把 1 视为 true, 把 0 视为 false
取反运算,对应位为 1,结果为 0,否则为 1 相当于一般逻辑运算符 ! ,把 1 视为 true, 把 0 视为 false
异或运算,对应位值相同,结果为 0,否则为 1 相当于一般逻辑运算符 equals ,把 1 视为 true, 把 0 视为 false
二、位移运算
左移运算,对应位整体向左移动 n 位,低位补 0, 高位溢出的舍去 相当于乘以 2 的 n 次方
正数右移运算,对应位整体向右移动 n 位,高位补 0, 低位溢出的舍去 相当于除以 2 的 n 次方
负数右移运算,对应位整体向右移动 n 位,高位补 1, 低位溢出的舍去
无符号右移运算,对应位整体向右移动 n 位,高位补 0, 低位溢出的舍去 相当于除以 2 的 n 次方
三、极端位移测试
左移运算,对应位整体向左移动 n 位,低位补 0, 高位溢出的舍去 若 n > 32, 相当于乘以 2 的 n % 32 次方
四、低精度整型位移运算