2

私はビットシフトが初めてで、このシフトをいつ使用するか知りたいですか? 以下のメソッドは、整数を 2 進数、8 進数、および 16 進数に変換します。ここで、「シフト」は 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

まず、引数の説明が間違っていると思います。これは、引数shiftが 2 ではなく 1 の場合にバイナリを生成します。

それが機能する方法は、メソッドが最初に、最下位 (最下位)ビットが 1であることを除いて、すべてゼロの値になるように計算maskすることです。少しずつ。(代入は右にシフトし、左はゼロで埋められます。メソッドが代入を誤って使用した場合、符号ビットで埋められます。) ループは 0 に達すると停止します。ループの代わりにループを使用することにより、メソッドは、0 から始まる場合でも、常に何らかの出力を生成します。intshiftshiftiishift>>>=>>=ido...whilewhilei

おそらく最も厄介な部分は、ウェイmaskが計算された結果、正確に 1 に設定される最下位shiftビットになることを認識することです。式の値は 2であるため、値 2 - 1 を取得します。これは常に1 のビットです。mask1 << shiftshiftmaskshiftshift

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

引数 47 と 3 を使用した簡単な例を次に示します。

radixは 8 に設定されます ( 1 << 3)
maskは 7 に設定されます (2 進数では 111)
i101111 のバイナリ値で始まります
charPos32 に設定され
ます 最初のループ反復:
    i & maskはビット パターン 111、つまり 7 です。
    charPosは 31 にデクリメント
    buf[31]されます 文字 '7'
    iに設定されます に設定され ますi >>> 3、またはバイナリ101 30 にデクリメントされます 文字 '5'に設定されます 0 に設定されます。ループ の終了 メソッドは、と の (32 - charPos =) 2 文字で形成された を返します。

    i & mask
    charPos
    buf[30]
    ii >>> 3
Stringbuf[30]buf[31]

結果: 47 の 8 進数表現は 57 です。

于 2013-08-08T15:41:40.247 に答える