基本情報技術者 2011年 秋期 午前(科目A) 問01
問題文
16ビットの2進数を16進数の各桁に分けて、下位の桁から順にスタックに格納するために、次の手順を4回繰り返す。a, bに入る適切な語句の組合せはどれか。ここで、XXXXは16進数XXXXを表す。
〔手順〕
(1) [ a ]をに代入する。
(2) をスタックにプッシュする。
(3) を[ b ]論理シフトする。

選択肢
ア:
イ:(正解)
ウ:
エ:
16ビット数を16進の各桁(ニブル)に分けてスタック格納する手順【午前2 解説】
要点まとめ
- 結論:正解は イ。各繰り返しで下位4ビットを取り出すには n AND を使い、次に右に4ビット論理シフトします。
- 根拠:AND が下位ニブルのみを抽出し、右に4ビット論理シフトすることで次の上位ニブルが下位位置に移動します。
- 差がつくポイント:論理シフトと算術シフトの違い、そしてマスクが下位か上位か( vs )を誤解しないことが重要です。
正解の理由
正解は イ です。手順の目的は「下位の桁から順に」スタックに格納することなので、毎回下位4ビット(ニブル)を取り出してスタックにプッシュし、その後で次のニブルを下位に移動させる操作が必要です。
- ステップ(1)で
x = n AND 000F₁₆
とすれば、 の下位4ビットのみが に入ります(1桁分の16進値)。 - ステップ(3)で
n
を右に4ビット論理シフトすると、元の上位ニブルが下位位置に入り、次回同じ操作で次の桁を取り出せます。 - 左シフトやマスク を使うと、取り出す値や移動方向が異なり、目的どおりに桁を順に得られません。
よって「a = n AND 000F₁₆、b = 右に4ビット論理シフト」が正しい組合せです。
よくある誤解
- 論理シフトと算術シフトを混同する:符号ビットを保持する算術右シフトだと負数時に1が詰められ、誤った値になります。符号に依存しない論理右シフトを使うべきです。
- マスクの向きを間違える( と の取り違え): は下位4ビット以外を残すマスクであり、単独でニブルを取り出せません。
- 左シフトで桁を移動させようとする誤り:左シフトは下位を0で埋め上げる方向に移動するため、繰り返すと正しい順序の桁が得られません。
解法ステップ
- 初期値として16ビット数 を用意する(例:)。
- 4回繰り返すループを実行する(16ビット / 4ビット = 4桁)。
- 各回で (1) (= AND )で下位ニブルを抽出し、(2) をスタックにプッシュする。
- (3) を右に4ビットの論理シフト()して、次のニブルを下位位置に移動させる。
- 4回終われば下位から上位へ順に格納された4桁が得られる。
具体例():
- 1回目: → push 0xD;(右4ビット論理シフト)
- 2回目: → push 0xC;
- 3回目: push 0xB;
- 4回目: push 0xA;終了
スタックに push した順は下位→上位なので、取り出す順(POP順)に注意してください。
# 例: Python(右シフトは論理ではなく符号無し扱いで実施)
n = 0xABCD
stack = []
for _ in range(4):
x = n & 0x000F
stack.append(x) # push
n = (n >> 4) & 0xFFFF # 16ビットを意識して論理的に扱う
print([hex(v) for v in stack]) # ['0xd','0xc','0xb','0xa']
選択肢別の誤答解説
-
ア(a = n AND 、b = 左に4ビット)
下位ニブルを取り出した後に左シフトすると、取り出した下位ニブルは左へ移動し、次回は正しい次のニブルが下位に来ません。したがって正しい順に桁を取得できません。 -
イ(a = n AND 、b = 右に4ビット)
正解。下位ニブル抽出→右シフトで次のニブルが下位に移動する流れが目的に合致します。 -
ウ(a = n AND 、b = 左に4ビット)
マスク は下位4ビットを切り落とすもので、1桁分の値を得られません。また左シフトも方向が不適切です。 -
エ(a = n AND 、b = 右に4ビット)
は単一ニブルの抽出に使えないため、x に入る値は期待する0〜15の16進1桁にならず不適切です。右シフトしても正しく桁を得られません。
補足コラム
- 代替手法:ビット演算の代わりに算術的に 、 を用いる方法もあります。高級言語では
%
と/
(整数除算)で実装可能です。 - 言語依存の注意:C言語などで右シフト演算子
>>
は符号付き整数の場合に算術シフト(符号ビットで埋める)になることがあるので、符号なし型(unsigned)を使うかマスクして論理シフト相当を確保してください。 - スタックの取り出し順:問題文で「下位の桁から順にスタックに格納する」とある場合、POPして取り出すと上位→下位の順になるため用途に応じてFIFO(キュー)や逆順処理を検討します。
FAQ
Q1: なぜ「論理」右シフトでなければならないのですか?
A1: 算術右シフトは符号ビットを複製するため、負の数だと1が詰められて正しいビットパターンになりません。ビット位置そのものを単純に下げたいので論理シフト(0を詰める)が必要です。
A1: 算術右シフトは符号ビットを複製するため、負の数だと1が詰められて正しいビットパターンになりません。ビット位置そのものを単純に下げたいので論理シフト(0を詰める)が必要です。
Q2: マスク を使う場面はありますか?
A2: はい。 は下位4ビットを消して上位12ビットを取り出したいときに有用ですが、単一のニブル(1桁)を取り出す目的には不向きです。
A2: はい。 は下位4ビットを消して上位12ビットを取り出したいときに有用ですが、単一のニブル(1桁)を取り出す目的には不向きです。
Q3: スタックにpushした順序と最終的な表示順の扱いは?
A3: push した順に下位→上位で積まれるため、POPして表示すると上位→下位で出ます。出力順が求められる順と逆なら、別途逆順に格納するか、最後にスタックを逆順処理してください。
A3: push した順に下位→上位で積まれるため、POPして表示すると上位→下位で出ます。出力順が求められる順と逆なら、別途逆順に格納するか、最後にスタックを逆順処理してください。
関連キーワード: 16ビット, 16進数, ニブル, スタック, ビット演算, 論理シフト, マスク, 下位桁, %演算, ビットシフト

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

