基本情報技術者試験対策(13)「シフト演算と符号拡張(2)」

スポンサーリンク
IT系

算術左シフトと加算による乗算

データの値を1ビットだけ算術左シフトすると、もとの値を2倍した結果が得られる。さらに、その結果を1ビットだけ算術左シフトすると、 2倍×2倍になるので、もとの値を4倍した結果が得られる。 さらに、 その結果を1 ビットだけ算術左シフトすると、2倍×2倍×2倍になるので、もとの値を8倍した結果が得られる。このように、算術左シフトで実現できるのは、2倍、 4倍、8倍、16倍、 ・・・という2のべき乗の乗算だけである。

3倍、5倍、10倍などの、2のべき乗でない乗算を実現したい場合は、 算術左シフトと加算を組み合わせる。 例えば、 3倍したい場合は、1ビットだけ算術左シフトして2倍になった値と、 もとの値を加算すれば、 2倍+1倍で3倍になる。 5倍したい場合は、2ビットだけ算術左シフトして4倍になった値と、元の値を加算すれば、4倍+1倍で5倍になる。

倍率シフト操作シフト後の値加算する値計算式(2進数の考え方)結果(10進数の例:x=10 の場合)
2倍左に1ビットx << 12×x20
3倍左に1ビット(x << 1) + x元のx2×x + 1×x = 3×x30
4倍左に2ビットx << 24×x40
5倍左に2ビット(x << 2) + x元のx4×x + 1×x = 5×x50
6倍左に2ビット(x << 2) + (x << 1)4×x + 2×x = 6×x60
7倍左に2ビット(x << 2) + (x << 1) + x元のx4×x + 2×x + 1×x = 7×x70
8倍左に3ビットx << 38×x80

具体例(x = 6 の場合)

倍率計算式結果
3倍(6 << 1) + 6 = (12) + 618
5倍(6 << 2) + 6 = (24) + 630

例題2.4は、算術左シフトと加算で3倍する方法を選ぶ問題である。ここでは 「非負(マイナスの数ではない)」と示されているので、符号ビットのことを考慮する必要はない。データの入れ物のサイズが示されていないので左シフトして最上位桁からはみ出す桁を考慮する必要もない。

例題2.4 2進数を3倍にする方法(H24春問2)

問2 非負の2進数b1b2…bnを3倍にしたものはどれか。

ア b1b2…bn0+b1b2…bn
イ b1b2…bn00-1
ウ b1b2…bn000
エ b1b2…bn1

1ビットだけ算術左シフトした結果 +元の値=2倍+1倍=3倍になる。b1b2…bnを1ピットだけ算術左シフトした結果は、 b1b2…bn0である。 これに元との値を足すので、 b1b2…bn0+b1b2…bnとなる。 正解は、選択肢アである。

算術右シフトによる除算

算術右シフトによる除算で実現できるのは、 1/2、 1/4、1/8、1/16、 2のべき乗分の1だけである。 算術右シフトと他の演算を組み合わせて、1/3、1/5、1/10 などの、任意の除算を行うことはできない。

任意の除算を実現したい場合は、引き算を繰り返すという方法がある
わかりやすいように10進数で例を示すと、 100÷3という除算を行う場合は、100から3を引くことを繰り返して、引けた回数と余りを求める。 全部で33 回引けて1余るので、 100÷3の商は33で、余りは1であることがわかる。

符号拡張

コンピュータの内部にあるデータの入れ物のサイズには、8ビット、 16ビッ ト、 32ビット、 64ビットなどがある。 大きな入れ物に格納されたデータ を、小さな入れ物に格納することはできない。 入りきらない上位桁が失われてしまうからである。 小さな入れ物に格納されたデータを、 大きな入れ物に格納することならできる。 空いた上位桁を0で埋めればよいからである。 ただし、2の補数表現のマイナスの値の場合は、空いた上位桁を1で埋める。 0で埋めると、 同じ値にならないからである。

例えば、8ビットの00000001というプラスの値を16ビットの入れ物に格納する場合は、空いた上位桁を0で埋めて0000000000000001とする。 8ビッ トの11111111というマイナスの値を16ビットの入れ物に格納する場合は、 空いた上位桁を1で埋めて1111111111111111とする。

プラスの値の符号ビットは0であり、マイナスの値の符号ビットは1である。 したがって、 小さな入れ物に格納されたデータを大きな入れ物に格納するときは、値がプラスであってもマイナスであっても、 符号ビットと同じ値で上位桁を埋めればよいのである。 まるで上位桁に向かって符号ビットを「グィ~ン」と拡張しているように見えるので、これを符号拡張と呼ぶ

例:8ビット → 16ビット に符号拡張する場合

種類8ビットの値符号ビット拡張方法16ビットに拡張後値(10進数)
正の値の例000000010上位を0で埋める00000000 00000001+1
別の正の値010101010上位を0で埋める00000000 01010101+85
負の値の例111111111上位を1で埋める11111111 11111111-1
別の負の値111101001上位を1で埋める11111111 11110100-12

仕組みのポイント

ポイント説明
✔️ 符号ビット(最上位ビット)0 → 正の数 / 1 → 負の数
✔️ 正の数上位をすべて0で埋めても値は変わらない
✔️ 負の数上位をすべて1で埋めることで、2の補数の形式が維持され、負のままの値を保てる
✔️ ビット長を拡張しても数値の意味は変わらない8ビットの -1 (11111111) → 16ビットの -1 (1111111111111111)

参考)情報処理教科書 出るとこだけ!基本情報技術者[科目A][科目B]2025年版


コメント

タイトルとURLをコピーしました