2

次の方法を使用して、整数の最上位のゼロ以外のバイトを抽出する方法があります。

private static int getFirstByte(int n)
{
    while (n > 0xFF)
        n >>= 8;

    return n;
}

この方法には論理的な問題があります。整数パラメーターは負になる可能性があります。これは、渡された数値が返されることを意味しますが、これは正しくありません。

メソッド自体にも問題がある可能性があります。while ループを使用しています。

while ループを使用せずにこのロジックを実行し、負の数に対して誤って返される結果を回避する方法はありますか?

4

3 に答える 3

3

巧妙ではなく、エレガントではありませんが、「ループを使用せずに、整数で最も重要なゼロ以外のバイトを抽出する」と信じています。

private static int getFirstByte(int n) {
  int i;
  if ((i = n & 0xff000000) != 0)
     return (i >> 24) & 0xff;
  if ((i = n & 0xff0000) != 0)
    return (i >> 16) & 0xff;
  if ((i = n & 0xff00) != 0)
    return (i >> 8) & 0xff;
  // all of the higher bytes are zeroes
  return n;
}
于 2012-12-28T06:45:41.143 に答える
2

log n / log 256…を使用することもできますが、そうすると、より大きな問題が発生します。

于 2012-12-28T06:40:41.523 に答える
1

最初の非ゼロを取得することで、動的な 8 ビット ブレークではなく、自然な 8 ビット ブレークを意味byteすると思います。intint

自然な 8 ビット ブレーク:

00000000|00010110|10110010|11110001==>00010110

動的 8 ビット ブレーク:

00000000000|10110101|1001011110001==>10110101

これは、ループまたは分岐なしbyteの自然な 8 ビット ブレークで最初の非ゼロを返します。このコードは、の回答intよりも効率的である場合とそうでない場合があります。paulsm4コードのベンチマークやプロファイリングを行って、どちらが最適かを判断してください。

Java コード: ideone link

class Main {
    public static void main(String[] args) {
        int i,j;
        for (i=0,j=1; i<32; ++i,j<<=1) {
          System.out.printf("0x%08x : 0x%02x\n",j,getByte(j));
        }
    }
    public static byte getByte(int n) {
        int x = n; 
        x |=   (x >>>  1);
        x |=   (x >>>  2);
        x |=   (x >>>  4);
        x |=   (x >>>  8);
        x |=   (x >>> 16);
        x -=  ((x >>>  1) & 0x55555555);
        x  = (((x >>>  2) & 0x33333333) + (x & 0x33333333));
        x  = (((x >>>  4) + x) & 0x0f0f0f0f);
        x +=   (x >>>  8);
        x +=   (x >>> 16);
        x &= 0x0000003f;
        x  = 32 - x;     // x now equals the number of leading zeros
        x &= 0x00000038; // mask out last 3 bits (cause natural byte break)
        return (byte)((n&(0xFF000000>>>x))>>>(24-x));
    }
}
于 2013-01-27T20:27:37.077 に答える