2012-03-03 4 views
0

これは、(i長い)Long.javaにnumberOfLeadingZerosある:Long.javaのnumberOfLeadingZeros(long i)がfloor(log2(x))= 63 - numberOfLeadingZeros(x)に基づいているとは思わない!

public static int numberOfLeadingZeros(long i) { 
     // HD, Figure 5-6 
     if (i == 0) 
      return 64; 
     int n = 1; 
     int x = (int)(i >>> 32); 
     if (x == 0) { n += 32; x = (int)i; } 
     if (x >>> 16 == 0) { n += 16; x <<= 16; } 
     if (x >>> 24 == 0) { n += 8; x <<= 8; } 
     if (x >>> 28 == 0) { n += 4; x <<= 4; } 
     if (x >>> 30 == 0) { n += 2; x <<= 2; } 
     n -= x >>> 31; 
     return n; 
} 

と著者は、それが基づいている前記床(LOG2(X))= 63 - numberOfLeadingZeros(X)またはCEIL(LOG2(X) )= 64 - numberOfLeadingZeros(x - 1)、それは本当ですか?それとも、私は理解できないほど愚かですか?

私にそれを説明できる誰か?ありがとう!

+0

* "わかりませんが、私は理解できないほど愚かですか?" * - 私たちはその質問に答えることはできません:-)。 –

+0

:>。時々私はばかです! – liuxiaori

答えて

2

番号の桁数は、(正しい塩基でログで)floor(log(num)) + 1総桁スペースがXである場合には、先行ゼロの数で、あなたのケースでそう

x - (floor(log(num)) + 1) = 
(x - 1) - floor(log(num)) 

あります64の総桁数とバイナリ

leadingZeros(num) = 63 - floor(log_2(num)) 

編集中の数:

>>>が解除されJavaで符号付き右シフト演算子と<<は左シフトです。 n >>> 32は、nを32ビット右にシフトし、空のスペースを0で埋めます。

次のようにアルゴリズムが動作する:

0000000000000000000000000000000000000000000001011010100000101011 
  1. 右シフトにi 32ビットxのみ上位32ビットが含まれてなります。

    00000000000000000000000000000000

  2. (a)は、これが0であれば、我々は、上位32ビットが0であった知っているので、先頭のゼロカウントに32を追加し、下位32ビットに集中します。 (b)それ以外の場合、これは0ではないので、数値の先頭にゼロが32未満です。上位32ビットに集中する。

  3. シフトx右に16ビット。

    同じプロセスで

    0000000000000101

    :これが0の場合(a)は、先行ゼロカウント数に16を追加し、次の最下位16ビットに集中(それらをシフトすることにより、我々が取り組んでいる地域に残さ)(b)これがゼロでない場合、追加する先行ゼロが16未満ではありません。

  4. 次のバイト、次に次の4ビット、2ビット、および最終ビットについて繰り返す。

+0

はい、私はそれを知っています。混乱している私の意味です。なぜ「n」を使うのか、最後の行の意味は何ですか?n - = x >>> 31 – liuxiaori

0

はい、xを符号なし番号と見なすことが条件です。

+0

は、Javaには符号なし番号がありますか? – liuxiaori

+0

@liuxiaori - そうですが、符号なしの数値を符号なしとして解釈することができます。 –

+0

ああ、私は無署名のnumber.hahaの単一のタイプがあることを意味します – liuxiaori

関連する問題