• java 的原码、补码、反码小总结


    先看一个代码吧:

    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

    这个应该很熟悉吧,是 java 里 HashMap 的计算 hash 值的方法.这里有一个运算符 "^",他其实就是使用补码来运算的.好了,那么我们下面来说说这些吧:

     
     >原码。
     就是当前数字的二进制表现形式,如-1的原码是1000 0001>反码
     正数的反码就是本身。负数的反码是二进制保留符号位。剩余位取反,比如-1的反码是1111 1110>补码
     正数的反码、补码、原码都是一样的,负数的补码是在其反码的基础上+1,比如-1的补码是1111 1111。
    
    
    正数的原码、反码、补码都相同。
    
    负数的反码是除符合位为1外,其他位全取反,简单地说,负数求补码,“反码加1“。
    这句话是不负责任的,因为原码、反码和补码概念中,存在符号位,总结一下,”取反加1“时符号位怎么办:
      1)取反时,符号位不参与取反。
      2)加1时,符号位参与加1。
      3)特殊补码,即首位为1,其它位全是0。对于这种形式的补码,不要去求它的原码了,求出来也不对,它就表示该类型中的最小负数,比如10000000表示byte类型中的最小负数-128。
    
    已知一个数的补码,求原码的操作分两种情况:
      1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码.
      2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取 反,然后再整个数加1.
      例如,已知一个补码为11111001,则原码是10000111(-7):因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”;其余7位1111001取反后为0000110;再加1,所以是10000111.
    
    
    java有7种位运算符:与(&),或(|),异或(^),取反(~),左移(<<),有符号右移(>>),无符号右移(>>>)。
    这7种位运算符,运算时,符号位都要参与运算。
    
    具体的规则如下:
      &    如果相对应位都是1,则结果为1,否则为0    (A&B),得到12,即0000 1100
      |    如果相对应位都是0,则结果为0,否则为1    (A | B)得到61,即 0011 1101
      ^    如果相对应位值相同,则结果为0,否则为1    (A ^ B)得到49,即 0011 0001
      〜 按位补运算符翻转操作数的每一位,即0变成1,1变成0。    (〜A)得到-61,即1100 0011
      << 按位左移运算符。左操作数按位左移右操作数指定的位数。    A << 2得到240,即 1111 0000
      >> 按位右移运算符。左操作数按位右移右操作数指定的位数。    A >> 2得到15即 1111
      >>>按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。    A>>>2得到15即0000 1111
     
    
    //1.&
    int a = 10,b = 6;
    /**
     * a = 10 > 00000000 00000000 00000000 00001010
     * b = 6  > 00000000 00000000 00000000 00000110
     * &
     * 2 >      00000000 00000000 00000000 00000010
     */
    System.out.println(Integer.toBinaryString(a));
    System.out.println(Integer.toBinaryString(b));
    System.out.println(a & b);
    
    a = -10;
    b = -6;
    
    /**
     * a = -10 > 11111111 11111111 11111111 11110110
     * b = -6  > 11111111 11111111 11111111 11111010
     * &
     * r = -14 > 11111111 11111111 11111111 11110010
     */
    
    //-10
    // 原码 10000000 00000000 00000000 00001010
    // 反码 11111111 11111111 11111111 11110101
    // 补码 11111111 11111111 11111111 11110110
    
    //-6
    // 原码 10000000 00000000 00000000 00000110
    // 反码 11111111 11111111 11111111 11111001
    // 补码 11111111 11111111 11111111 11111010
    
    // -14
    // 原码 10000000 0000000 00000000 00001110
    // 反码 11111111 1111111 11111111 11110001
    // 补码 11111111 1111111 11111111 11110010
    
    System.out.println("a = " + a + ",补码是:" + Integer.toBinaryString(a));
    System.out.println("b = " + b + " ,补码是:" + Integer.toBinaryString(b));
    System.out.println("a ^ b is:" + (a & b));
    System.out.println("结果的补码是:" + Integer.toBinaryString(-14));
  • 相关阅读:
    vue----webpack模板----axios请求
    vue-----meta路由元信息
    vue----webpack模板----全局路由守卫
    vue----webpack模板----局部路由守卫
    vue----webpack模板----组件复用解决方法
    vue----webpack模板----编程式导航
    vue----webpack模板----路由跳转的3中方式
    vue----webpack模板----路由传值
    vue----webpack模板----children子路由,路由嵌套
    vue----webpack模板----路由配置项
  • 原文地址:https://www.cnblogs.com/zhuzi91/p/8818950.html
Copyright © 2020-2023  润新知