余腾

导航

Java源码分析四(Integer)

Java源码分析四(Integer)

类中的属性分析

    下面两个属性定义了Integer能存储数据的最大值和最小值 因为int是32位 所以最大值为2的31次方-1、最小值为2的31次方。
    @Native public static final int   MIN_VALUE = 0x80000000;
    @Native public static final int   MAX_VALUE = 0x7fffffff;
    此属性返回基本数据类型int对应反射的类 与Integer.getClass不是同一个
    public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
    下面定义一个方便存储int值和转换toString的char【】数组 作用 根据下标和对应的进制找到对应的值 比如16进制 15 他的存储数据就是f
     final static char[] digits = {
        '0' , '1' , '2' , '3' , '4' , '5' ,
        '6' , '7' , '8' , '9' , 'a' , 'b' ,
        'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
        'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
        'o' , 'p' , 'q' , 'r' , 's' , 't' ,
        'u' , 'v' , 'w' , 'x' , 'y' , 'z'
    };
     下面定义了一个数组作用取出一个数的十位数 如87将取出8 99取出9 下面用到会详细讲解
     final static char [] DigitTens = {
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
        '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
        '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
        '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
        '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
        '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
        '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
        '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
        '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
        } ;
        这个是取出个位数 如86取出6
        final static char [] DigitOnes = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        } ;
      定义了Integer所占的位数32位也就是int的位数
      @Native public static final int SIZE = 32;
      定义了所占字节 为 32/8=4;
      public static final int BYTES = SIZE / Byte.SIZE;
      序列号
      @Native private static final long serialVersionUID = 1360826667806852920L;
      包装类包装的数据
      private final int value;

构造器

  //传入一个int值 直接将包装的数据传过去
 public Integer(int value) {
        this.value = value;
    }
    //传入一个String s 通过parseInt(以10进制格式)转换为int值并传给value
 public Integer(String s) throws NumberFormatException {
        this.value = parseInt(s, 10);
    }

一个内部类IntegerCache(缓冲池也可以认为是常量池存储-128到127的Integer)

 private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
            //缓冲池的长度为256
            cache = new Integer[(high - low) + 1];
             //意思是cache[0]=-128
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

Integer的几种创建形式解析

1: 通过构造器创建 两种构造器  ->开辟新的空间每次创建都是一个新的对象都在堆中开辟一个新空间
public Integer(int value);
public Integer(String s);
2:通过对象等于一个int值创建:如Integer i=2;内存解析 他默认调用Integer i=Integer.value(2) 此方法调用缓冲区的数据 
如果i在-128到127之间返回缓冲区中的数据如果超过就创建一个新的对象
3:通过Integer的valueOf创建对象如上面解释相同
 public static Integer valueOf(int i) ;
public static Integer valueOf(String s) throws NumberFormatException >默认调用十进制的parseInt方法后得到int 后调用上面第一个方法
public static Integer valueOf(String s, int radix) throws NumberFormatException ->根据s 和传入的radix(你想转换的进制)
得到一个int值后调用第一个方法
4:通过getInteger进行对象创建:讲方法的时候再说
public static Integer getInteger(String nm);
public static Integer getInteger(String nm, Integer val)
public static Integer getInteger(String nm, int val)

Integer的方法解析

  //根据进制将你输入的int值转换String格式 i传入的想要转换的值 radix 需要转换的进制
 public static String toString(int i, int radix) {
        //如果进制大于32或者进制小于2让他默认转换为10进制
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;

        /* Use the faster version */
      //如果进制是10进制直接计算 讲toString再说 很简单
        if (radix == 10) {
            return toString(i);
        }
        //定义33位长度 为什么是33位呢 如果是符号给他一个符号位“-”如果是正就没必要显示了 int占位32位
        char buf[] = new char[33];
        //判断是否需要加“-”
        boolean negative = (i < 0);
        //默认倒着写数据 定义一个默认指针 指向你想存储位置
        int charPos = 32;
        //默认以负数格式计算 其实我觉得也可以按照正数计算 下面toString 就是按照正数算的 我感觉挺好用还可以用位运算
        if (!negative) {
            i = -i;
        }
        //不多解释 根据进制取模后将取模后的值存入字符串 如18 改16进制 第一步 buf[32]=digits[2]; i=-2
        while (i <= -radix) {
            buf[charPos--] = digits[-(i % radix)];
            i = i / radix;
        }
        //将剩下的2直接丢入到charpos
        buf[charPos] = digits[-i];
        //判断是否加入“-”
        if (negative) {
            buf[--charPos] = '-';
        }

        return new String(buf, charPos, (33 - charPos));
    }
    //根据你传入的i(正数)和进制进行转换 这里是无符号转换 一定要是正数 负数会出现补码计算出来的越界问题数据不准
  public static String toUnsignedString(int i, int radix) {
        return Long.toUnsignedString(toUnsignedLong(i), radix);
    }
     //将一个正数i转换为16进制 下方的toUnsignedString0再说
public static String toHexString(int i) {
        return toUnsignedString0(i, 4);
    }
    //将一个正数转换为8进制
 public static String toOctalString(int i) {
        return toUnsignedString0(i, 3);
    }
    //将一个正数转换为2进制
  public static String toBinaryString(int i) {
        return toUnsignedString0(i, 1);
    }
          //所有的正数通过进制转换string  shift是偏移量 16进制就是2的4次方 也就是偏移4个单位 shift=4
 private static String toUnsignedString0(int val, int shift) {
        // assert shift > 0 && shift <=5 : "Illegal shift value";
        //获取需要开辟的空间大小 如3 转换为2进制 mag=32-30=2;
        int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
        //获取创建数组的长度
        int chars = Math.max(((mag + (shift - 1)) / shift), 1);
        char[] buf = new char[chars];
        //马上说
        formatUnsignedInt(val, shift, buf, 0, chars);

        // Use special constructor which takes over "buf".
        return new String(buf, true);
    }
      //将char[] buf进行添加数据 并返回遍历到那个位置了
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
        //起始位置
        int charPos = len;
        //算出进制
        int radix = 1 << shift;
        下面有一个很好的算法需要用到
        int mask = radix - 1;
        do {
            //这句话很厉害 i&mask 这个如果i是正数就相当于val%mask 众所周知位运算的速度远远远大于模运算故很强 
            //想了解具体怎么算的可以看一下与运算的规则很厉害
            buf[offset + --charPos] = Integer.digits[val & mask];
            val >>>= shift;
        } while (val != 0 && charPos > 0);

        return charPos;
    }
    //i是最小值的时候直接返回 如果不是 开辟对应的size空间用来存储数据如果是负数则多开辟一个符号位
 public static String toString(int i) {
        if (i == Integer.MIN_VALUE)
            return "-2147483648";
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        char[] buf = new char[size];
        //加工数组用的 等下说
        getChars(i, size, buf);
        return new String(buf, true);
    }
    //加工字符串
static void getChars(int i, int index, char[] buf) {
        int q, r;
        //老规矩定义节点 倒着遍历
        int charPos = index;
        //符号位
        char sign = 0;
        //获取符号位 并统一按照正数处理这就是为什么最小值让他直接返回 如果是最小值他的正数就越界了 
        if (i < 0) {
            sign = '-';
            i = -i;
        }
        //不多BB很简单 就是数字过大时候 以100除 一次加工两个字符 
        // Generate two digits per iteration
        while (i >= 65536) {
            q = i / 100;
        // really: r = i - (q * 100);
            r = i - ((q << 6) + (q << 5) + (q << 2));
            i = q;
            buf [--charPos] = DigitOnes[r];
            buf [--charPos] = DigitTens[r];
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i <= 65536, i);
        for (;;) {
           //是除10, 乘法代替除法并用位运算 很厉害 为什么想到的不知道 反正就是除以10,
            q = (i * 52429) >>> (16+3);
            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
            //下面就是加工字符串没什么好说的
            buf [--charPos] = digits [r];
            i = q;
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign;
        }
    }
      //获取输入x的为数 很简单没什么好说的
 static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
    }
    //最重要的parseInt 也是用到最多的我们默认调用的parseInt(String s) 是他的重写相当于parseInt(String s  10);
 public static int parseInt(String s, int radix)
                throws NumberFormatException
    {
        /*
         * WARNING: This method may be invoked early during VM initialization
         * before IntegerCache is initialized. Care must be taken to not use
         * the valueOf method.
         */
          // 字符串不能为空
        if (s == null) {
            throw new NumberFormatException("null");
        }
        //进制不能小于2
        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }
        //进制不能大于2
        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }
         //返回的值
        int result = 0;
        //判断符号用的
        boolean negative = false;
        int i = 0, len = s.length();
        //最小值为-MAX_VALUE 如果MIN_VALUE会出现越界问题
        int limit = -Integer.MAX_VALUE;
        int multmin;
        int digit;

        if (len > 0) {
            char firstChar = s.charAt(0);
            //判断你输入的是+还是-
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {
                    //确定是负数后 最小值改为MIN_VALUE
                    negative = true;
                    limit = Integer.MIN_VALUE;
                } else if (firstChar != '+')
                    throw NumberFormatException.forInputString(s);

                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                i++;
            }
            multmin = limit / radix;
            //具体运算规则看一下吧
            while (i < len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                digit = Character.digit(s.charAt(i++),radix);
                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }
                if (result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
        return negative ? result : -result;
    }
    //调用了上面的方法
    public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }
//无符号的String s 转换成对应的进制
public static int parseUnsignedInt(String s, int radix)
                throws NumberFormatException {
        if (s == null)  {
            throw new NumberFormatException("null");
        }

        int len = s.length();
        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar == '-') {
                throw new
                    NumberFormatException(String.format("Illegal leading minus sign " +
                                                       "on unsigned string %s.", s));
            } else {
                //如果len>9越界 如果是转换成2进制 最大值转换为32进制只需要6位空间 转换成10进制需要10个空间
                if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
                    (radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
                    return parseInt(s, radix);
                } else {
                    long ell = Long.parseLong(s, radix);
                    if ((ell & 0xffff_ffff_0000_0000L) == 0) {
                        return (int) ell;
                    } else {
                        throw new
                            NumberFormatException(String.format("String value %s exceeds " +
                                                                "range of unsigned int.", s));
                    }
                }
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
    }
      //无符号转换为10进制
  public static int parseUnsignedInt(String s) throws NumberFormatException {
        return parseUnsignedInt(s, 10);
    }
    //将对应的s 和进制radix  转换成一个int后 用valueof(int i)
 public static Integer valueOf(String s, int radix) throws NumberFormatException {
        return Integer.valueOf(parseInt(s,radix));
    }
      //默认十进制
 public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }
      //如果输入的i在-128到127中直接去缓冲区中找然后返回 防止资源浪费 如果不在就给他new一个对象
 public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    //将数据强转成byte格式下面类似的只贴代码不做解释
  public byte byteValue() {
        return (byte)value;
    }
 public short shortValue() {
        return (short)value;
    }
  public int intValue() {
        return value;
    }
public long longValue() {
        return (long)value;
    }
public float floatValue() {
        return (float)value;
    }
public double doubleValue() {
        return (double)value;
    }
      //对象调用的 可以理解为类调用将本对象的value值传过去 很简单
  public String toString() {
        return toString(value);
    }
  //返回hashCode
  public int hashCode() {
        return Integer.hashCode(value);
    }
    //hashCode值就是 value值 
public static int hashCode(int value) {
        return value;
    }
      //重写的equals 只比较 value 
  public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
      //Integer.getInteger(String)的功能是根据指定的名称得到系统属性的整数值。
      //第一个参数将被认为是系统属性的名称。系统属性可以通过 System.getProperty(java.lang.String)方法访问得到。
     //属性值字符串将被解释成一个整数,并且以表示这个值的Integer对象形式返回。可能出现的数字格式的详细说明可以在 getProperty 的定义说明里找到。
    //Integer.getInteger(String)方法假设String参数是一个系统属性数值的名称,
    //会读取该系统属性,然后把系统属性的值转换成一个数字。
    //也就是说, Integer.getInteger("12345") 应该是得到 null(假设没有名为12345的系统属性)。
public static Integer getInteger(String nm) {
        return getInteger(nm, null);
    }
public static Integer getInteger(String nm, int val) {
        Integer result = getInteger(nm, null);
        return (result == null) ? Integer.valueOf(val) : result;
    }
    //先判断一下 如果nm对应的属性名称存不存在 不存在直接返回 val  如果存在进行计算
public static Integer getInteger(String nm, Integer val) {
        String v = null;
        try {
            v = System.getProperty(nm);
        } catch (IllegalArgumentException | NullPointerException e) {
        }
        if (v != null) {
            try {
                //具体计算规则 
                return Integer.decode(v);
            } catch (NumberFormatException e) {
            }
        }
        return val;
    }
    //刚才系统遍历的Integer值的具体计算规则
public static Integer decode(String nm) throws NumberFormatException {
        int radix = 10;
        int index = 0;
        boolean negative = false;
        Integer result;

        if (nm.length() == 0)
            throw new NumberFormatException("Zero length string");
        char firstChar = nm.charAt(0);
        // Handle sign, if present
        if (firstChar == '-') {
            negative = true;
            index++;
        } else if (firstChar == '+')
            index++;

        // Handle radix specifier, if present
        if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
            index += 2;
            radix = 16;
        }
        else if (nm.startsWith("#", index)) {
            index ++;
            radix = 16;
        }
        else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
            index ++;
            radix = 8;
        }

        if (nm.startsWith("-", index) || nm.startsWith("+", index))
            throw new NumberFormatException("Sign character in wrong position");

        try {
            result = Integer.valueOf(nm.substring(index), radix);
            result = negative ? Integer.valueOf(-result.intValue()) : result;
        } catch (NumberFormatException e) {
            // If number is Integer.MIN_VALUE, we'll end up here. The next line
            // handles this case, and causes any genuine format error to be
            // rethrown.
            String constant = negative ? ("-" + nm.substring(index))
                                       : nm.substring(index);
            result = Integer.valueOf(constant, radix);
        }
        return result;
    }
      //将本对象的value值个另一个需要比较的Integer对象value进行比较
public int compareTo(Integer anotherInteger) {
        return compare(this.value, anotherInteger.value);
    }
    //可以通过类调用的比较方法  传入两个参数 如果大就返回-1否则0
  public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }
    //判断正数的大小 这个效率更快 先让他直接加上MIN_VALUE然后比较
 public static int compareUnsigned(int x, int y) {
        return compare(x + MIN_VALUE, y + MIN_VALUE);
    }
  //转换成long类型的正数
 public static long toUnsignedLong(int x) {
        return ((long) x) & 0xffffffffL;
    }  
      //返回两个数的除法数据(前提是俩都是正数 否则出现越界就不准了)
 public static int divideUnsigned(int dividend, int divisor) {
        // In lieu of tricky code, for now just use long arithmetic.
        return (int)(toUnsignedLong(dividend) / toUnsignedLong(divisor));
    }
    //获取俩正数的模运算
   public static int remainderUnsigned(int dividend, int divisor) {
        // In lieu of tricky code, for now just use long arithmetic.
        return (int)(toUnsignedLong(dividend) % toUnsignedLong(divisor));
    }
    // 获取最高位是1后面补0的数  如 9他就是1001 那么经过计算后1000就是8
public static int highestOneBit(int i) {
1、第一步的作用是把最高位1右移移位,并与原数据按位取或。那么这就使得最高位和它的下一位是连续两个1。
2、第二步的作用是把刚刚移位得到连续两个1继续右移两位并与原数据按位取或。那么这就使得最高两位和它的下两个连续位组成四个连续的1。
3、 以此类推,最终得到的i是从开始的最高位到结束全是1。并减去i不带符号的右移一位,即可得到一个int数据的最高位的值。
4、上述情况是针对于i不为零和负数的情况,如果i为零,那么得到的结果始终为零。如果i位负数,那么得到的结果始终是-2147483648。
即等于Integer.MIN_VALUE。(原因在于负数的最高位始终为1,即是负数的符号位)
 
此函数的最重要理解点在与要始终把握二进制的最高位进行运算处理,那么对于函数中的右移一位、两位、四位、八和十六位就好理解了。
同理,对于long类型的取最高位运算应该需要加一条语句 i|=(i>>32); 原因在于long类型在Java中是64位的。

        // HD, Figure 3-1
        i |= (i >>  1);
        i |= (i >>  2);
        i |= (i >>  4);
        i |= (i >>  8);
        i |= (i >> 16);
        return i - (i >>> 1);
    }
    //此方法就比较人性化了输入的值可以是正数也可以是负数 返回最后一位是1后面补0的数据
public static int lowestOneBit(int i) {
        // HD, Section 2-1
        //下面为大家介绍一下 如果计算的 举个栗子 :4吧 比较小好写 XXX代表中间很多0就不写了 YYY 代表无数个1
        //4 的原码为 0XXX100  反码0XXX100 补码 0XXX100 (真好算)
        // -4的源码  1XXX100  反码1YYY011 补码1YYY100 
        //开始与运算了 0XXX100 在算一下 这不就是4嘛 返回就完事了
        return i & -i;
    }
 //很简单返回前面最多有几个0  如4 0XXX100 一共32位前29个是0就返回29 
// 首先在jvm中一个int类型的数据占4个字节,共32位,其实就相当于一个长度为32的数组。
// 那我们要计算首部0的个数,就是从左边第一个位开始累加0的个数,直到遇到一个非零值。
public static int numberOfLeadingZeros(int i) {
		if (i == 0)                                                                       
            	return 32;
		int n = 1;
		// 下面的代码就是定位从左边开始第一个非零值的位置,在定位过程中顺便累加从左边开始0的个数
		// 将i无符号右移16位后,有二种情况;
		//   情况1.i=0,则第一个非零值位于低16位,i至少有16个0,同时将i左移16位(把低16位移到原高16位的位置,这样情况1和情况2就能统一后续的判断方式)
		//   情况2.i!=0,则第一个非零值位于高16位,后续在高16位中继续判断
		// 这个思路就是二分查找,首先把32位的数分为高低16位,如果非零值位于高16位,后续再将高16位继续二分为高低8位,一直二分到集合中只有1个元素
		if (i >>> 16 == 0) { n += 16; i <<= 16; }
		// 判断第一个非零值是否位于高8位
		if (i >>> 24 == 0) { n +=  8; i <<=  8; }  
		// 判断第一个非零值是否位于高4位
		if (i >>> 28 == 0) { n +=  4; i <<=  4; }
		// 判断第一个非零值是否位于高2位
		if (i >>> 30 == 0) { n +=  2; i <<=  2; }       
		// 判断第一个非零值是否位于左边第一位
		n -= i >>> 31;                                                                
		return n;
	}
    //思路与上面类似 这个是最右边第几个0
 public static int numberOfTrailingZeros(int i) {
        // HD, Figure 5-14
        int y;
        if (i == 0) return 32;
        int n = 31;
        y = i <<16; if (y != 0) { n = n -16; i = y; }
        y = i << 8; if (y != 0) { n = n - 8; i = y; }
        y = i << 4; if (y != 0) { n = n - 4; i = y; }
        y = i << 2; if (y != 0) { n = n - 2; i = y; }
        return n - ((i << 1) >>> 31);
    }
    //统计有多少个1  比如9 是0XXX1001 那么就返回2  计算规则自己看看吧 不太重要 就是个位运算的小计算
public static int bitCount(int i) {
        // HD, Figure 5-2
        i = i - ((i >>> 1) & 0x55555555);
        i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
        i = (i + (i >>> 4)) & 0x0f0f0f0f;
        i = i + (i >>> 8);
        i = i + (i >>> 16);
        return i & 0x3f;
    }
    //左移 相当于乘2 负数不是 反正就是补码往左移 因为负数的补码特殊 
   public static int rotateLeft(int i, int distance) {
        return (i << distance) | (i >>> -distance);
    }
    //右移同样不适用与负数
 public static int rotateRight(int i, int distance) {
        return (i >>> distance) | (i << -distance);
    }
    //转换为2禁止 然后转 比如1是0XXX1 反转就是1XXX0 那么他就是最小值-2147483648 
  public static int reverse(int i) {
        // HD, Figure 7-1
        i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
        i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
        i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
        i = (i << 24) | ((i & 0xff00) << 8) |
            ((i >>> 8) & 0xff00) | (i >>> 24);
        return i;
    }
    //获取符号位 负数返回-1 正数返回1 ,区分负数正数的时候用 无符号右移(-i >>> 31);这个决定
public static int signum(int i) {
        // HD, Section 2-7
        return (i >> 31) | (-i >>> 31);
    }
     // OK 结束 下面不说了
 public static int sum(int a, int b) {
        return a + b;
    }
 public static int max(int a, int b) {
        return Math.max(a, b);
    }
public static int min(int a, int b) {
        return Math.min(a, b);
    }

posted on 2021-09-10 18:54  余腾  阅读(198)  评论(0编辑  收藏  举报

Fork me on Gitee