& | ^ ~ >> >>>

Java基础复习才发现入门时对于数据类型没有学通,这次学通啦

复杂点在符号右移和无符号右移方面,正负数的移位方式不一样。

阅读前提:

1. 计算机程序中只有2进制。

2. 理解 原码、反码、补码 ,知道 byte1字节、short 2字节、char 2字节、int 4字节、float 4字节等

3.明白 与 或 亦或 按位取反 类型强转

4. 数据在内存中用补码表示

5.16进制数默认是int类型,使用16进制强转byte来获得负数,便于阅读

6.代码中写的16进制数实际上是一个整数的补码 比如 (byte)0xc5 表示负数

7.短整数(1、2字节)无符号右移会变成长整数(4字节)

8. 请注意,0xXX默认是Int类型的补码

代码部分:

package datatype;

public class Logical {

    public static void main(String[] args) {
        System.out.println("------------与或非--------------");
        // 提取低位的半个字节
        System.out.println("01010101 & 0x00ff 结果为"+(0x55 & 0x0f));
        // 按位或 
        // 在socket通信DataInputStream.readUnsignedShort()中用来合并byte
        System.out.println("00001111 | 11110000 结果为:"+(byte)(15 | 15 << 4));
        // 按位亦或
        System.out.println("01011100 ^ 11111010 结果为:"+(0x5c ^ 0xfa));// 10100110 0xa6

        System.out.println(Integer.toBinaryString(0xaf));
        int a = ((int)0x8a)|((int)0x05);
        System.out.println(Integer.toBinaryString(a)+"
a:"+(-1|a));
        
        System.out.println(Integer.toBinaryString((int)((0x87 - 0x01) ^ 0xff))+"十进制:-"+""+(int)((0x87 - 0x01) ^ 0xff));
        System.out.println(Integer.toBinaryString(1));
        System.out.println("------------按位取反-------------");
        // 数值取反
        System.out.println(Integer.toBinaryString(~(9-0x01)));
        System.out.println(Integer.toBinaryString(-9));
        
        System.out.println("------------类型强转--------------");
        // 所有整数在内存中均用补码表示
        // 0x8f = 1000 1111 ; 1000中 1为符号位,表示负数 ;
        // 1000 1111 (补码) ---> 1000 1110 (反码) ----> 1111 0001 (原码)
        // 所以 0x8f 表示  -(7*16 + 1) = -113
        System.out.println((byte)0x8f);
        
        short s = (short) 0x80ff;
        // 0x80ff -->  10000000 11111111 (补码,符号位1,表示负数) ---> 10000000 11111110 (反码) 
        // ---> 11111111 00000001 (原码) = -(7*16^3 + 15*16^2 +1) = 28672 + 3840 + 1 = -32513
        System.out.println("0x80ff:"+s);
        
        // 输出 0xc5 = 1100 0101 符号位为1; 补码11000101-->反码11000100-->原码10111011= -(3*16+11) = -59
        System.out.println("0xc5:"+(byte)0xc5);
        System.out.println("------------符号右移-------------");
        // 负数符号右移 高位补1
        // 0xc5=1100 0101(补码) --> 1100 0100 (反码) --> 1011 1011 (原码) = -(3*16+11) = -59
        // 0xc5=1100 0101 --> 右移一位 1110 0010 = 0xe2 
        // -30 = 1001 1110 (原码) <-- 1110 0001 <-- 1110 0010 (补码)= 0xe2
        System.out.println("(byte)0xc5>>1:"+((byte)0xc5>>1));
        // 正数符号右移 高位补0
        // 0101 0101 >>1 --> 0010 1010 = 0x2a = 2*16+10 = 42
        System.out.println("(byte)0x55>>1:"+((byte)0x55>>1));
        
        System.out.println("------------无符号右移------------");  //注意 0xc5默认是正整数int类型4字节,为了获得负数,强转为byte类型1字节
        // 正数无符号右移 高位补0
        System.out.println("(byte)0x55>>>1:"+((byte)0x55>>>1));
        // 负数无符号右移 高位补0
        // 0xc5= 1100 0101 >>>1   0111 1111 1111 1111 1111 1111 1110 0010 = 0x7fffffe2
        // 0xc5= 1100 0101 >>>2   0x7ffffff1
        System.out.println("(byte)0xc5>>>1:"+((byte)0xc5>>>1));
        // -5 原码   10000000 00000000 00000000 00000101 反码 11111111 11111111 11111111 11111010
        // 补码 11111111 11111111 11111111 11111011 = 0xfffffffb >>>1 补码无符号右移1位  最高位为0 
        // 结果 01111111 11111111 11111111 11111101 = 0x7ffffffd
        System.out.println(-5>>>1==0x7ffffffd);
        /*
           -6 原码 10000000 00000000 00000000 00001000 反码 11111111 11111111 11111111 11110111
               补码 11111111 11111111 11111111 11111000 无符号右移两位 01111111 11111111 11111111 11111110 = 0x7ffffffe
           3ffffffe
           0x00111111 11111111 11111111 11111110
         */
    }
}

原文地址:https://www.cnblogs.com/zhengwenqiang/p/7884270.html