基本情報技術者 2015年 春期 午前(科目A) 問01
問題文
次に示す手順は、列中の少なくとも一つは1であるビット列が与えられたとき、最も右にある1を残し、他のビットを全て0にするアルゴリズムである。例えば、00101000が与えられたとき、00001000が求まる。aに入る論理演算はどれか。
手順1 与えられたビット列Aを符号なしの2進数と見なし、Aから1を引き、結果をBとする。
手順2 AとBの排他的論理和(XOR)を求め、結果をCとする。
手順3 AとCの[ a ]を求め、結果をAとする。
選択肢
ア:排他的論理和(XOR)
イ:否定論理積(NAND)
ウ:論理積(AND)(正解)
エ:論理和(OR)
🔒 解説は解答すると表示されます
最右の1ビット抽出【午前解説】
正解の理由
与えられた手順は、A-1によって最右の1を0にし、より下位の0を1に反転させます。AとA-1のXOR(C)は最右の1を含むそれより下位すべてが1になります。最後にAとCの論理積(AND)を取ると、Aに元からあるビットのうちCで1となっている箇所だけが残り、結果として最も右にある1だけが残ります。したがって a に入る論理演算は「論理積(AND)」です。
解法ステップ
- A を確認し、少なくとも1ビットが立っていることを前提とする。
- B = A - 1 とする。A-1 は最右の1を0にし、それより下位のビットをすべて反転する。
- C = A XOR B を計算すると、最右の1と下位全てが1になっているビットマスクが得られる。
- A = A AND C を計算すると、AのうちCで1になっている位置だけが残り、最も右の1だけが抽出される。
- 以上より a は「論理積(AND)」。
選択肢別の誤答解説
- ア: 排他的論理和(XOR)
- 誤り。AとCをXORすると、Cの1がAで1でない部分まで影響し、複数ビットが立つ結果になり目的を達成しません。
- イ: 否定論理積(NAND)
- 誤り。NANDはANDの否定であり、ビットマスクとして使うと反転した不必要な1が残るため不適切です。
- ウ: 論理積(AND)
- 正解。AとCのANDは、Cが示す範囲(最右の1と下位)からAに元々あるビットだけを抽出し、結果的に最も右の1だけを残します。
- エ: 論理和(OR)
- 誤り。ORを使うとCの領域すべてが1になり、最右の1以外のビットも1になってしまいます。
よくある誤解
- 「XORを使えば良い」と単純に思い込み、最後にAとCをXORしてしまうと複数ビットが残り正解になりません。
- Aが0の場合を考慮せずに「常に成り立つ」としてしまうと境界ケースで誤答になります(問題では少なくとも1つ1がある前提)。
- 2の補数や借りの発生によるビット反転の意味を理解していないと、なぜA-1が下位ビットを反転するかが混乱します。
補足コラム
この操作は「最下位セットビット(least significant set bit)」を抽出する典型的なビットハックです。より短い表現として、符号付整数の2の補数を使える環境では次の式が同等です:
C言語やPython等では以下のように書けます(Aは0でないことが前提):
// C の例
unsigned int lowbit = A & -A;
# Python の例(任意幅整数に対しても動作します)
lowbit = A & -A
用途としてはビット全探索で低位の1を順に取り出す処理(A & -A で取り出し、A -= lowbit で消去)や、集合をビットで表したアルゴリズムでの最小要素取得などがあります。
FAQ
Q1: なぜA-1で下位ビットが反転するのですか?
A1: 10...0 の形(最右の1が位置kで、それより下がすべて0)から1引くと,位置kの1が0になり,下位の0は借りを受けてすべて1に変わるためです。
A1: 10...0 の形(最右の1が位置kで、それより下がすべて0)から1引くと,位置kの1が0になり,下位の0は借りを受けてすべて1に変わるためです。
Q2: A が 0 の場合はどうなりますか?
A2: 問題の前提で「少なくとも一つは1がある」としているため考慮不要ですが、A=0だとA-1は全ビット1(符号なしでは最大値)になるためこの手順は想定外の動作になります。
A2: 問題の前提で「少なくとも一つは1がある」としているため考慮不要ですが、A=0だとA-1は全ビット1(符号なしでは最大値)になるためこの手順は想定外の動作になります。
Q3: 他に同じ結果を得る方法はありますか?
A3: はい。2の補数を使う方法で A & (-A) とすれば同じく最下位の1を取り出せます。
A3: はい。2の補数を使う方法で A & (-A) とすれば同じく最下位の1を取り出せます。
Q4: 負の数や符号付き整数でも同じですか?
A4: ビット幅固定で2の補数表現を前提とする場合は同様に動作しますが、符号付きのオーバーフロー挙動や未定義動作に注意してください。符号なし演算を用いるのが安全です。
A4: ビット幅固定で2の補数表現を前提とする場合は同様に動作しますが、符号付きのオーバーフロー挙動や未定義動作に注意してください。符号なし演算を用いるのが安全です。
関連キーワード: ビット演算、最下位ビット、2の補数、ビットハック、論理積、排他的論理和、マスク操作

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

