2

我是移位新手,想知道何时使用这种移位?下面的方法将整数转换为二进制、八进制和十六进制,其中“移位”将是 2,3 或 4,而 i 是任何整数。

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

在哪里

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

我无法理解这种方法。请解释。

4

1 回答 1

3

First, I think that your description of the arguments is wrong. This will generate binary when the argument shift is 1, not 2.

The way it works is that the method first calculates mask to be an int value that is all zero except for the bottom (least significant) shift bits are 1. The loop then repeatedly looks up the digit corresponding to the least significant shift bits of i and then shifts i to the right by shift bits. (The >>>= assignment shifts to the right and fills with zero on the left. If the method had incorrectly used the >>= assignment, it would fill with the sign bit.) The loop stops when i reaches 0. By using a do...while loop instead of a while loop, the method always generates some output, even if i starts as 0.

Perhaps the trickiest part is realizing that the way mask is computed results in exactly the bottom shift bits of mask being set to 1. The expression 1 << shift has the value of 2shift, so mask gets the value 2shift - 1, which is always shift bits of 1.

1 << shift:
   000000...000010  .  .  .  0
                 |<- shift ->|
                     bits
                     all 0
(1 << shift) - 1:
   000000...000001  .  .  .  1
                 |<- shift ->|
                     bits
                     all 1

Here's a simple example with arguments 47 and 3:

radix is set to 8 (1 << 3)
mask is set to 7 (111 in binary)
i starts with binary value of 101111
charPos is set to 32
First loop iteration:
    i & mask is bit pattern 111, which is 7;
    charPos is decremented to 31
    buf[31] is set to the character '7'
    i is set to i >>> 3, or binary 101
Second loop iteration:
    i & mask is 101, which is 5;
    charPos is decremented to 30
    buf[30] is set to the character '5'
    i is set to i >>> 3, which is 0; the loop ends
The method returns the String formed by the (32 - charPos =) 2 characters at buf[30] and buf[31].

Result: the octal representation of 47 is 57.

于 2013-08-08T15:41:40.247 回答