算術左シフトと加算による乗算
データの値を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 << 1 | ― | 2×x | 20 |
| 3倍 | 左に1ビット | (x << 1) + x | 元のx | 2×x + 1×x = 3×x | 30 |
| 4倍 | 左に2ビット | x << 2 | ― | 4×x | 40 |
| 5倍 | 左に2ビット | (x << 2) + x | 元のx | 4×x + 1×x = 5×x | 50 |
| 6倍 | 左に2ビット | (x << 2) + (x << 1) | ― | 4×x + 2×x = 6×x | 60 |
| 7倍 | 左に2ビット | (x << 2) + (x << 1) + x | 元のx | 4×x + 2×x + 1×x = 7×x | 70 |
| 8倍 | 左に3ビット | x << 3 | ― | 8×x | 80 |
具体例(x = 6 の場合)
| 倍率 | 計算式 | 結果 |
|---|---|---|
| 3倍 | (6 << 1) + 6 = (12) + 6 | 18 |
| 5倍 | (6 << 2) + 6 = (24) + 6 | 30 |
例題2.4は、算術左シフトと加算で3倍する方法を選ぶ問題である。ここでは 「非負(マイナスの数ではない)」と示されているので、符号ビットのことを考慮する必要はない。データの入れ物のサイズが示されていないので左シフトして最上位桁からはみ出す桁を考慮する必要もない。
(例題2.4) 2進数を3倍にする方法(H24春問2)
問2 非負の2進数b1b2…bnを3倍にしたものはどれか。
ア b1b2…bn0+b1b2…bn
イ b1b2…bn00-1
ウ b1b2…bn000
エ b1b2…bn11ビットだけ算術左シフトした結果+元の値==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進数) |
|---|---|---|---|---|---|
| 正の値の例 | 00000001 | 0 | 上位を0で埋める | 00000000 00000001 | +1 |
| 別の正の値 | 01010101 | 0 | 上位を0で埋める | 00000000 01010101 | +85 |
| 負の値の例 | 11111111 | 1 | 上位を1で埋める | 11111111 11111111 | -1 |
| 別の負の値 | 11110100 | 1 | 上位を1で埋める | 11111111 11110100 | -12 |
仕組みのポイント
| ポイント | 説明 |
|---|---|
| ✔️ 符号ビット(最上位ビット) | 0 → 正の数 / 1 → 負の数 |
| ✔️ 正の数 | 上位をすべて0で埋めても値は変わらない |
| ✔️ 負の数 | 上位をすべて1で埋めることで、2の補数の形式が維持され、負のままの値を保てる |
| ✔️ ビット長を拡張しても数値の意味は変わらない | 8ビットの -1 (11111111) → 16ビットの -1 (1111111111111111) |
(参考)情報処理教科書 出るとこだけ!基本情報技術者[科目A][科目B]2025年版


コメント