ビットシフトがどのように機能するかを理解しようとしています。誰かがこの行の意味を説明できますか?
while ((n&1)==0) n >>= 1;
ここn
で、は整数でn
、シフトが実行されたときの例を示します。
ビットシフトがどのように機能するかを理解しようとしています。誰かがこの行の意味を説明できますか?
while ((n&1)==0) n >>= 1;
ここn
で、は整数でn
、シフトが実行されたときの例を示します。
それを分解する:
n & 1
nとバイナリの1の間でバイナリ比較を行い00000000000000000000000000000001
ます。00000000000000000000000000000001
そのため、nが1(正の奇数または負の偶数)で終わる場合などに戻り00000000000000000000000000000000
ます。
(n & 1) == 0
したがって、nが偶数(または負の奇数)の場合はtrueになり、それ以外の場合はfalseになります。
n >> = 1
と同等n = n >> 1
です。そのため、すべてのビットが右にシフトします。これは、2で割った値(切り捨て)にほぼ相当します。
たとえば、nが12として開始された場合、バイナリでは1100になります。1つのループの後は110(6)になり、次のループは11(3)になり、ループは停止します。
nが0の場合、次のループの後も0のままであり、ループは無限大になります。
n
バイナリで次のよう4
に表されます。
00000000 00000000 00000000 00000100
(n&1)
をビットごとに ANDn
し1
ます。1
次のバイナリ表現があります。
00000000 00000000 00000000 00000001
ビットごとの論理積の結果は次のとおりです0
。
00000000 00000000 00000000 00000100 = n
00000000 00000000 00000000 00000001 = 1
------------------------------------
00000000 00000000 00000000 00000000 = 0
そのため、while の条件は true です。の最下位ビットを抽出するために
効果的に使用されました。(n&1)
n
while ループでは、右に shift( >>
) n
by 1
. 数値を で右シフトすることk
は、数値を で割ることと同じ2^k
です。
n
どちらが今00000000 00000000 00000000 00000100
右シフトで一度になり
ます00000000 00000000 00000000 00000010
か2
。
n
次に、再び whichの LSB (最下位ビット) を抽出し、再度0
右シフトして、00000000 00000000 00000000 0000001
which isを求めます1
。
次に、現在の n の LSB を再度抽出1
し、ループを中断します。
したがって、奇数にはLSBが設定されているため、奇数になるまで数値n
を効果的に分割し続けます。2
また、何回割っても奇数にはならないため、最初から無限ループに入ることに注意しn
てください。0
0
2
n = 12と仮定します。このためのビットは1100(1 * 8 + 1 * 4 + 0 * 2 + 0 * 1 = 12)になります。1100の最後の桁が0であるため、最初にループn&1 == 0を通過し、それを1とANDすると、0になります。したがって、n >> = 1の場合、nは1100(12)から110に変更されます。 (6)。お気づきかもしれませんが、右にシフトすると2で割るのと同じ効果があります。最後のビットはまだゼロなので、nと1は0のままなので、もう一度右にシフトします。n >> = 1を指定すると、さらに1桁右にシフトし、nが110(6)から11(3)に変わります。
これで、最後のビットが1であることがわかります。したがって、nと1は1になり、whileループの実行が停止します。ループの目的は、最初のオンになっているビットが見つかるまで(結果が奇数になるまで)、数値を右にシフトすることであるように見えます。
等しいと仮定しましょう42
(理由だけ):
int n = 42;
while ((n & 1) == 0) {
n >>= 1;
}
反復 0:
n = 42
(または0000 0000 0000 0000 0000 0000 0010 1010
)n & 1 == 0
ですtrue
(n&1 = 0 または のため0000 0000 0000 0000 0000 0000 0000 0000
)反復 1:
n = 21
(または0000 0000 0000 0000 0000 0000 0001 0101
)n & 1 == 0
はfalse
(n & 1 == 1
または のため0000 0000 0000 0000 0000 0000 0000 0001
)機能:
基本的に、n が偶数である限り、ループで n を 2 で除算します。
たとえば、nが
n= b11110000
それから
n&1= b11110000 &
b00000001
---------
b00000000
n>>=1 b11110000 >> 1
---------
b01111000
n= b01111000
ループが続く場合は、
n= b00001111
n&1は、実際にはビット単位のAND演算です。ここで、nのビットパターンは1のビットパターンに対してANDEDされます。誰の結果がゼロと比較されます。はいの場合、nは1回右シフトされます。1つの右シフトを2で割るなどのように取ることができます。