/**
 * @author WanJl
 * @version 1.0
 * @title Demo06
 * @description 位运算符
 * @create 2026/7/14
 */
public class Demo06 {
    /*
        位运算符是用来直接操作 整型（byte/short/int/long/char）的二进制位，性能极高，在底层编程、权限控制、编码算法中使用的比较多

        &           按位与         5&3             0101 & 0011  = 0001
        |           按位或         5|3             0101 & 0011  = 0111
        ^           按位异或       5^3             0101 & 0011  = 0110
        ~           按位取反       ~5              ~0101 = 1010
        <<          按位左移       5<<1            0101 << 1 = 1010
        >>          按位右移       5>>1            0101 >> 1 = 0010
        >>>         无符号右移     5>>>1           0101 >> 1 = 0010


     */
    public static void main(String[] args) {
        // 按位与 & 符号左右两边的数的每个二进制位，如果同时为1，则运算结果为1，否则为0，然后再把二进制数转换为十进制数
        //比如 5 & 3
        // 0101
        // 0011
        // 0001
        System.out.println(5&3); //1
        // 按位或 | 符号左右两边的数的每个二进制位，如果同时为0，则运算结果为0，否则为1，然后再把二进制数转换为十进制数
        //比如 5 | 3
        // 0101
        // 0011
        // 0111
        System.out.println(5|3);    //7
        // 按位异或 ^ 符号左右两边的数的每个二进制位，如果相同则为0，不同则为1，然后再把二进制数转换为十进制数
        //比如 5 ^ 3
        // 0101
        // 0011
        // 0110
        System.out.println(5^3);    //6
        // 按位取反 单目运算符，符号右边的数的二进制位，如果为0，则运算结果为1，如果为1，则运算结果为0
        //比如 ~5 8位
        // 0000 0101
        // 1111 1010
        System.out.println(~5); //-6

        //按位左移 << 把符号左边的数的二进制位，向左移动符号右边的个数，空出来的位置补0
        // 5<<1
        // 0101
        // 1010     末位补0
        System.out.println(5<<3);   //把符号左边的5的二进制数0101，向左移动符号右边个数 3，空出来的位置补0

        // 按位右移 >> 把符号左边的数的二进制位，向有移动符号右边的个数，空出来的位置补【符号位】的值
        // 二进制数的最左侧为最高位，也就是符号位，符号位如果是0，那么这个二进制数就是正数，如果是1，这个二进制数就是负数
        //  8位2进制数  1010 1111   这就是负数
        //  16位2进数   0000 0000 1010 1111  这就是正数
        // 5>>1
        // 0101
        // 0010     右侧多出来的1，被截断。左侧空出来的补符号位 0

        System.out.println(5>>3);   //6 把符号左边的5的二进制数0101，向右移动符号右边个数 3，空出来的位置补符号位

        //无符号右移 >>> 把符号左边的数的二进制位，向有移动符号右边的个数，空出来的位置补0
        // 8位 -5
        // 1111 1011
        // 0111 1101

        System.out.println(-5>>>1); // 把符号左边的-5的二进制数1111 1011，向右移动符号右边个数 1，空出来的位置补0，从负数变为正数

        /*
            左移：高位丢失，低位补0，相当于 ×2
            右移：低位丢失，高位补符号位，相当于 ÷2   并且向下取整
            无符号右移：低位丢失，高位补0，对负数会得到大正数
         */
        /*
            编程运行，查看结果
            15>>3
            66<<2
            75&86
            63|36
            -128>>>3
         */
    }
}
