【问题标题】:Please explain the method from Integer class请解释 Integer 类的方法
【发布时间】:2013-08-08 15:31:22
【问题描述】:

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

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

【问题讨论】:

  • 这绝对不能回答你的问题,但这个链接可能对你有用:graphics.stanford.edu/~seander/bithacks.html
  • 您是否尝试过单步执行该方法(手动或使用调试器)?你不明白哪一部分?
  • (右移 == 除法,左移 == 乘法)2 ^ 移位的位数。这可能有助于您了解实际情况。
  • @TedHopp 感谢您的评论。我没有得到掩码和位移背后的逻辑

标签: java operators bit-manipulation


【解决方案1】:

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

它的工作方式是该方法首先计算 mask 为一个除底部(最低有效)shift 位为 1 之外全为零的 int 值。然后循环重复查找该数字对应于i 的最低有效shift 位,然后将i 向右移动shift 位。 (&gt;&gt;&gt;= 赋值向右移动并在左侧填充零。如果该方法错误地使用了 &gt;&gt;= 赋值,它将用符号位填充。)当i 达到 0 时循环停止。使用do...while 循环而不是while 循环,该方法总是会生成一些输出,即使i 以0 开头。

也许最棘手的部分是意识到mask 的计算方式导致mask 的底部shift 位被设置为1。表达式1 &lt;&lt; shift 的值为2@987654339 @,所以mask 的值是 2shift - 1,它始终是 shift 的 1 位。

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

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

radix 设置为 8 (1 &lt;&lt; 3)
mask 设置为 7(二进制 111)
i 以二进制值 101111 开头
charPos 设置到 32
第一次循环迭代:
i &amp; mask 是位模式 111,即 7;
charPos 减为 31
buf[31] 设置为字符“7”
i 设置为 i &gt;&gt;&gt; 3,或二进制 101
第二次循环迭代:
i &amp; mask是101,也就是5;
charPos 减为 30
buf[30] 设置为字符“5”
i设置为i &gt;&gt;&gt; 3,即为0;循环结束
该方法返回由buf[30]buf[31] 处的(32 - charPos =) 2 个字符组成的String

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

【讨论】:

  • 也许补充一下为什么屏蔽技巧有效(1 n-1 lsb 中全为 1 的数字
  • @fvu - 完成,同时模拟一个可能有助于此的典型呼叫。
  • @TedHopp 感谢您的宝贵解释。这解释了这种方法是如何工作的。清除。但是为什么我们使用 lsb 来掩盖 no。位,使其与数组索引匹配?
  • @user1682878 因为这种掩码的行为类似于模运算符 - number &amp; ( 1 &lt;&lt; n ) - 1 == number % ( 1 &lt;&lt; n ) 即结果将始终满足 0 &lt;= result &lt;= ( 1 &lt;&lt; n ) - 1
  • @user1682878 - and-ing 与 lsb 掩码生成一个介于 0 和 (2^shift)-1 之间的值;这可以很好地用作digits 数组的索引。因为循环生成从最低有效位置开始的数字,buf 数组需要从右侧填充,这就是为什么charPos 从 32 开始并向下的原因。
猜你喜欢
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 2014-02-17
  • 1970-01-01
相关资源
最近更新 更多