数値の大きさを見つけるための同様の O(1) ビット単位のトリックはありません。多くのマイクロプロセッサ命令セットには、「先頭のゼロをカウントする」ための特別な命令が含まれています。C 言語ファミリには、JavaScript にビット単位の機能を与えるような演算子はありません。
O(1) の唯一の代替手段はMath.floor( Math.log( n ) / Math.LN2 )、
for ( var i = 0; i == Math.floor( Math.log( 1<<i ) / Math.LN2 ); ++ i ) ;
演算子が 32 ビットの 2 の補数の符号付き算術演算を使用i == 31しているため、結果として が得られます。<<
純粋主義者になりたい場合は、O( log n) である 1 だけ繰り返し右シフトするか16 >> i、i0 から 4 まで繰り返し右シフトして、結果が 0 の場合はシフトを拒否し、それ以外の場合は を累積し16 >> iます。これは O(log log N) です。ここで、N は の最大値でnあり、一定の時間を意味しますが、すべての確率で よりも遅くなりMath.logます。
O( log log N ) アルゴリズムのコード:
var mag = function( n ) {
var acc = 0;
for ( var i = 16; i; i >>= 1 ) {
if ( n >> i ) {
n >>= i;
acc += i;
}
}
return acc;
};
もちろん、これらのいずれについても、インデックスではなく「左端の 1 ビット」を取得するために、結果を 1 つ左にシフトする必要があります。
編集:logベースの実装は-Infinity0 を返しますが、関数magは を返しますが0、これは の結果と同じです1。最左端の 1 ビットが存在しない可能性を考慮したい場合は、特殊なケースにすることをお勧めします。