数据结构

Java 负数二进制转换、位移、位运算

2019-08-22  本文已影响0人  xujicheng

Java 中 int型->32bit
范围-2147483648~2147483647
[1000,0000,0000,0000,0000,0000,0000,0000~0111,1111,1111,1111,1111,1111,1111,1111]
其中左起最高位是符号位 1表示负数 0表示正数

  1. 正负数如何转换呢

例如:5 [0000,0000,0000,0000,0000,0000,0000,0101]

  1. 左位移 <<
    例如:

     //5 [0000,0000,0000,0000,0000,0000,0000,0101] 
     int i = 5 << 1;
     //[0000,0000,0000,0000,0000,0000,0000,1010]  = 10
     int I = 5 << 2;
     // [0000,0000,0000,0000,0000,0000,0001,0100]  = 20
    
     //6 [0000,0000,0000,0000,0000,0000,0000,0110] 
     int i = 6 << 1;
     //  [0000,0000,0000,0000,0000,0000,0000,1100] =12
     int I = 6 << 2;
     //  [0000,0000,0000,0000,0000,0000,0001,1000] =24
    

二进制左移一位,其实就是将数字翻倍

  1. 右位移 >>
    例如 :
//5 [0000,0000,0000,0000,0000,0000,0000,0101] 
  int i = 5 >> 1;
  //[0000,0000,0000,0000,0000,0000,0000,0010]  = 2
  int I = 5 >> 2;
  // [0000,0000,0000,0000,0000,0000,0000,0000]  = 1

  //6 [0000,0000,0000,0000,0000,0000,0000,0110] 
  int i = 6 >> 1;
  //  [0000,0000,0000,0000,0000,0000,0000,0011] =3
  int I = 6 << 2;
  //  [0000,0000,0000,0000,0000,0000,0000,0001] =1

二进制右移一位,就是将数字除以 2 并求整数

  1. 右位移 >> 和 >>>的区别

Java中定义了2种右移:逻辑右移>>>和算术右移>>
目的是为了符号位是1是否右移。
逻辑右移>>>一位 左边补0
算术右移>>一位 左边补1
验证一下:

        System.out.println(Integer.toBinaryString(Integer.MIN_VALUE));
        System.out.println(Integer.MIN_VALUE);
        System.out.println(Integer.toBinaryString(Integer.MIN_VALUE>>>1));
        System.out.println(Integer.MIN_VALUE>>>1);
        System.out.println(Integer.toBinaryString(Integer.MIN_VALUE>>1));
        System.out.println(Integer.MIN_VALUE>>1);

        /**
         * 10000000000000000000000000000000
         * -2147483648
         * 1000000000000000000000000000000
         * 1073741824
         * 11000000000000000000000000000000
         * -1073741824
         */
        System.out.println("----------------------------------------------");
        System.out.println(Integer.toBinaryString(Integer.MAX_VALUE));
        System.out.println(Integer.MAX_VALUE);
        System.out.println(Integer.toBinaryString(Integer.MAX_VALUE>>>1));
        System.out.println(Integer.MAX_VALUE>>>1);
        System.out.println(Integer.toBinaryString(Integer.MAX_VALUE>>1));
        System.out.println(Integer.MAX_VALUE>>1);

        /**
         * 01111111111111111111111111111111
         * 2147483647
         * 00111111111111111111111111111111
         * 1073741823
         * 00111111111111111111111111111111
         * 1073741823
         */

目前看 逻辑右移和算术右移只是对负数有区别,算术右移是带着符号位右移并补上原先的符号位。
那么左移是否会影响到符号位呢?
验证一下

        System.out.println(Integer.toBinaryString(Integer.MAX_VALUE));
        System.out.println(Integer.MAX_VALUE);
        System.out.println(Integer.toBinaryString(Integer.MAX_VALUE<<1));
        System.out.println(Integer.MAX_VALUE<<1);
        /**
         * 01111111111111111111111111111111
         * 2147483647
         * 11111111111111111111111111111110
         * -2
         */

可见左移永远只在末尾补0,会影响符号位。

  1. 位运算 & 、|、^

bit 0、1 分别代表了假、真

例如
2147483647 | -2 = -1

    01111111111111111111111111111111
    11111111111111111111111111111110
  ----逻辑或(|)------------------------
   =11111111111111111111111111111111
```
    System.out.println(Integer.toBinaryString(2147483647|-2));
    System.out.println(2147483647|-2);
    // -1 逻辑或任何数的结果都是-1
    System.out.println(Integer.toBinaryString(-1|4325));
    System.out.println(-1|4325);
    /**
     *11111111111111111111111111111111
     * -1
     * 11111111111111111111111111111111
     * -1
     */
```
    01111111111111111111111111111111
    11111111111111111111111111111110
  ----逻辑与(&)------------------------
   =01111111111111111111111111111110
```
    System.out.println(Integer.toBinaryString(2147483647&-2));
    System.out.println(2147483647&-2);
    /**
     * 01111111111111111111111111111110
     * 2147483646
     */
```

例如
2147483647 ^ -2 = 2147483646

    01111111111111111111111111111111
    11111111111111111111111111111110
  ----逻辑异或(^)------------------------
   =10000000000000000000000000000001
```
    System.out.println(Integer.toBinaryString(2147483647^-2));
    System.out.println(2147483647^-2);
    //所有的数异或自身都为0
    System.out.println(2345^2345);
    System.out.println(-2^-2);
    /**
     * 10000000000000000000000000000001
     * -2147483647
     * 0
     * 0
     */
```
上一篇下一篇

猜你喜欢

热点阅读