3

10010 のようなビットとして保存される 5 つの異なる値があります。データベースから値を Int として取得します (変更できません)。たとえば、24 は 11000 を意味します。

if ((decbin($d) & 16) == 16)

しかし、最初のビットが 0 の場合は次のビットをチェックする必要があり、それが 0 の場合は ...

結局のところ、ifs のブロックがあり、ビットが多ければブロックは大きくなります。最上位ビットの「ID」(または値、問題ではない) を 1 で取得する簡単な方法はありますか?

4

4 に答える 4

9

はい。数値の 2 を底とする対数を計算すると、次のようになりfloorます。

$highbit = floor(log($d, 2));

たとえば$highbit、 が 5 の場合、5 番目のビットが 1 に設定された最上位ビットであることを意味します。

于 2011-02-09T14:11:36.870 に答える
1

整数に設定される最上位ビットは、その整数の2を底とする整数の対数に等しくなります。

アセンブラやCなどでそのようなことを行うためのさまざまな実装がありますが、多かれ少なかれ効率的ですが、PHPでそれを行う最も簡単な方法は、実際に対数を使用することです。

log()関数は確かに問題を解決する最も効率的な方法ではありませんが、スクリプト言語を使用しているので、「より良い」アルゴリズムの1つを実装するよりも遅くなることはないでしょう。 PHPでは2ダースのステートメントがあります。

したがって:

$ highestbit =(int)(log($ value、2));

于 2011-02-09T14:15:00.377 に答える
0

興味深いことに、丸めの問題をすぐに確認する必要があり、最大 1'000'000 の範囲で何も見つかりませんでしたが、私のテスト コードでは、3 のようなネイティブ ベースの数が少ない問題が明らかになりました。

3^5 = 243 ですが、floor(log(243, 3)) は 4 を返します

于 2011-02-09T14:40:44.137 に答える
-1
def hibit(v):
    """ uint v -> highest bit: 0101 -> 0100, 01xxxx -> 010000 """
    # cf http://graphics.stanford.edu/~seander/bithacks.html
    v |= v >> 1
    v |= v >> 2
    v |= v >> 4
    v |= v >> 8
    v |= v >> 16
    return v ^ (v >> 1)

for v in range(0, 9+1) + range(2**31-1, 2**31+2):
    print v, hibit(v)
于 2011-02-18T17:07:40.160 に答える