请从Integer类解释该方法

时间:2013-08-08 15:31:23

标签: java operators bit-manipulation

我是新手,想要知道何时使用这种移位?下面的方法将整数转换为二进制,八进制和十六进制,其中“shift”为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'
};

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

1 个答案:

答案 0 :(得分:3)

首先,我认为您对参数的描述是错误的。当参数shift为1而不是2时,这将生成二进制文件。

它的工作方式是该方法首先将mask计算为int值,除了底部(最低有效)shift位为1之外,该值均为零。然后重复查找对应于shift的最低有效i位的数字,然后将i向右移shift位。 (>>>=赋值向右移动并在左边填充零。如果方法错误地使用了>>=赋值,它将填充符号位。)循环在{{1通过使用i循环而不是do...while循环,该方法始终生成一些输出,即使while从0开始。

也许最棘手的部分是意识到计算i的方式导致mask的{​​{1}}位被设置为1. shift表达式具有值为2 mask ,因此1 << shift得到值2 shift - 1,总是mask位1。

shift

这是一个带参数47和3的简单示例:

  

shift设置为8(1 << shift: 000000...000010 . . . 0 |<- shift ->| bits all 0 (1 << shift) - 1: 000000...000001 . . . 1 |<- shift ->| bits all 1
  radix设置为7(二进制为111)
  1 << 3以二进制值101111开始   mask设置为32
  第一次循环迭代:
  i是位模式111,其为7;
  charPos递减至31   i & mask设置为字符'7'   charPos设置为buf[31]或二进制101   第二次循环迭代:
  i是101,即5;
  i >>> 3递减至30   i & mask设置为字符'5'   charPos设置为buf[30],即0;循环结束
  该方法返回由ii >>> 3处的(32 - charPos =)2个字符组成的String

结果:47的八进制表示为57。