Java source code parsing Integer method interpretation

  • 2020-05-24 05:36:49
  • OfStack

toUnsignedString method interpretation

I saw that there is such a method in Integer to convert int into Unsigned type string, but there are a few points that are not very clear, and I understood them after querying the data. The interpretation is as follows:


 /**
   * Convert the integer to an unsigned number.
   */
  private static String toUnsignedString(int i, int shift) {
    char[] buf = new char[32];
    int charPos = 32;
    int radix = 1 << shift;
    int mask = radix - 1;
    do {
      buf[--charPos] = digits[i & mask];
      i >>>= shift;
    } while (i != 0);

    return new String(buf, charPos, (32 - charPos));
  }

The parameter shift here is the base, if it's a base 2 then shift is 2 and 8 then it's 8, and the corresponding mask is calculated as 1 and 7. Extract the corresponding characters from the digits array by mask and i.

Every time i performs a logical shift to the right, the highest bit is added with zero, so that i will eventually become 0 after a continuous logical shift to the right

In addition, do-while is used to prevent i itself from being 0 in the case that the buf array cannot get its value.

toString method interpretation


//  This array represents Numbers 10 The bit part, we're going to use this array. 
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',
    } ;

//  This array represents the units digit part of the number, and we'll use this array. If you combine each part of the array, you get this 100 Within all cases 2 An integer. 

  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',
    } ;

  public static String toString(int i) {
    if (i == Integer.MIN_VALUE)
    //  Here to add 1 I don't know what that means at first, but then I find negative Numbers. Right               
    //  You have to put a negative sign in front of it so you have to add the size of the string 1 To just go 
    //  Here the incoming stringSize Is positive in the array below 
    //  mapping 
    int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
    char[] buf = new char[size];
    getChars(i, size, buf);
    return new String(0, size, buf);
  }

  static void getChars(int i, int index, char[] buf) {
    int q, r;
    int charPos = index;
    char sign = 0;

    if (i < 0) {
      sign = '-';
      i = -i;
    }

    //  More than 65536 So let's do the following 1 A processing, 
    //  So we're going to do that 100 Is in units, that is, the remainder is in two digits 
    //  So that maps exactly to the top 10 Bits and units, 1 Time sex written 
    // buf Two in the array, so there's no question that we're going to solve for each 1 Bit is a lot faster 
    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 less than or equal to 65536 In terms of integers, you can proceed directly to the following part 
    //  And this right here is divided by PI 10 Yes, but the implementation does not divide directly 
    //  But seek first 1 a 52429/2^19 Approximately equal to the 0.1000...
    //  The equivalent of i Divided by the 10 But what I don't know is why isn't this straightforward 
    //  Divided by the 10 Maybe because it's not accurate enough, division produces floating point Numbers, 
    //  Maybe it's not exact, and then you get the divisor times that 10 , 10 More than a 
    //  Part of the number through i- This part 10 If you have more than one digit, you get the ones digit 
    for (;;) {
      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;
    }
  }

  final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                   99999999, 999999999, Integer.MAX_VALUE };

  //  Here it should be optimized through sizeTable The bits that store integer data 
  //  The case from 1 position 1 until 10 A: 2147483647 The situation, 
  //  It's a neat way to do it 
  static int stringSize(int x) {
    for (int i=0; ; i++)
      if (x <= sizeTable[i])
        return i+1;
  }

highestOneBit method interpretation


public static int highestOneBit(int i) {
    // HD, Figure 3-1
    i |= (i >> 1);
    i |= (i >> 2);
    i |= (i >> 4);
    i |= (i >> 8);
    i |= (i >> 16);
    return i - (i >>> 1);
  }

It's a very interesting method, and I figured it out myself, and then I figured it out, and what it does is it takes the value of the integer represented by the largest bit that makes up an integer. This is done by means of displacement. Now, for a simple example, 128 is the base 2 of 1000, 0000. Take him as an example:

Move one
1000 0000
0100 0000
|-------------
Move the two
1100 0000
0011 0000
|------------
Remove the four
1111 0000
0000 1111
|------------
Move the eight
1111 1111
0000 0000
|------------
Mobile 16
1111 1111
0000 0000
|------------
1111 1111

The end result, as you can see, is that all the bits behind are filled with 1, and all the bits behind are subtracted to get the integer represented by the highest bit.

bitCount method parsing


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;
  }

This method really wasted half a day of research, and finally I got the general idea:
So line 1, what you do is you take the integer 2 bits and you group them two by two, and you count the number of 1's in those two bits, and I don't know where this formula comes from, but it works.
In line 2, what you're doing is you're grouping the 2 bits of the integer into 4 bits, and then you're adding up the shifts in the segments, which is 1001- > So 10 plus 01 is 11 is the same thing as 3 ones
So line 3, you take the integer's base 2 bits and you have 8 1's, and you add up the displacements in the same way that you did above, and of course you do it with a certain shift and a sum.
And then you have 106 1's and 3102 1's and you merge the statistics into the last few bits of the statistics.


Related articles: