「符号ビット固定」は本当に固定なの? 算術左シフトで混乱しやすいポイントを整理する

広告

2の補数のシフト演算を学習していると、教材には

「符号ビット固定」

という説明がよく出てきます。

しかし、この表現だけを見ると、

「符号ビットは動かないの?」

という疑問を持つ方も少なくありません。

今回は、この「符号ビット固定」という言葉の意味を、実際のビット列を見ながら整理してみます。


元の値は -12

8ビットの2の補数で -12 は次のように表されます。

11110100

先頭が「1」なので負の数です。

本当に -12 なのか確認してみます。

まずビットを反転します。

00001011

さらに 1 を足します。

00001100

これは10進数で12です。

したがって、

11110100 = -12

となります。


左へ2ビットシフトする

この値を左へ2ビットシフトすると、

11110100 (-12)

左へ2ビットシフト

11010000 (-48)

※ 左からあふれた2ビットは捨てられ、右端には0が入ります。

となります。


図で確認してみましょう


本当に -48 になっている?

シフト後の

11010000

も先頭が1なので負の数です。

反転すると

00101111

1を足すと

00110000

になります。

これは

32 + 16 = 48

です。

つまり、

11010000 = -48

となります。


なぜ -48 になるの?

左シフトには次の性質があります。

  • 左へ1ビットシフト → ×2
  • 左へ2ビットシフト → ×4

したがって、

-12 × 4 = -48

になります。


オーバーフローには注意

ここで注意したいのは、

「左シフトすると必ず2倍・4倍になる」わけではない

ということです。

これは、

計算結果が、そのビット数で表現できる範囲内である場合に限ります。

例えば、8ビットの2の補数で表現できる範囲は

-128 ~ +127

です。

例えば、

01010000(+80)

を左へ1ビットシフトすると

10100000

になります。

数学では

80 × 2 = 160

ですが、

160は8ビットでは表現できません。

そのため、左端からあふれたビットが捨てられ、別のビット列になってしまいます。

つまり、

オーバーフローすると、本来の計算結果をそのビット数では正しく表現できなくなるのです。


「符号ビット固定」とは何を意味しているの?

ここが一番誤解しやすいところです。

「符号ビット固定」と書かれていると、

符号ビットだけは動かない

と思ってしまいがちです。

しかし、実際のCPUでは

11110100

左へ2ビットシフト

11010000

のように、8ビット全体を左へシフトしています。

CPUが

「ここは符号ビットだから動かさない」

という特別な処理をしているわけではありません。


「固定」の本当の意味

ここでいう「固定」とは、

「左端のビットを符号として解釈する」

という意味です。

つまり、

1 1110100
↑
このビットは符号を表す

という説明であり、

「このビットだけ動かない」という意味ではありません。


「算術左シフト」という表現について

教材によっては、「算術シフト」という表現で左シフトを説明しているものがあります。

しかし、多くのCPUでは、左シフトはビット列全体を左へ移動し、右端に0を入れる動作を行います。これは負の数でも同じです。

一方で、「符号ビットを保持する」という説明が重要になるのは、一般的には算術右シフトです。

そのため、「算術左シフトだから符号ビットを固定する」と受け取ってしまうと、かえって混乱の原因になることがあります。


教材のイラストについて感じたこと

今回見直した教材のイラストは、概念を分かりやすく伝えようとしたものだと思います。

一方で、初めて学ぶ人の立場で見ると、

  • 「符号ビット固定」という説明
  • 実際のビット列の変化
  • 計算結果

この3つの関係が少し分かりにくく感じました。

特に、図から読み取れるビット列と計算結果の対応が曖昧だと、

「符号ビットは固定なのに動いているように見える」

あるいは

「このビット列で本当に -48 になるの?」

という疑問を持ってしまうかもしれません。

教材は概念を分かりやすく伝えるために簡略化されることがあります。しかし、ビット演算のような内容では、実際のビット列を一つひとつ追いながら確認する方が理解しやすいと感じました。


ビット列を追うと理解しやすい

実際の変化を、1ビットずつ追ってみます。

11110100(-12)

↓ 左へ1ビット

11101000(-24)

↓ 左へもう1ビット

11010000(-48)

このように順番に確認すると、

  • 左シフト1回で2倍
  • 左シフト2回で4倍

という性質も自然に理解できます。


まとめ

「符号ビット固定」という表現は、それ自体が誤りというわけではありません。

ただし、その言葉だけを見ると、「符号ビットは動かない」と受け取ってしまう可能性があります。

重要なのは次の4点です。

  • CPUはビット列全体を左へシフトしている。
  • 左シフトは、オーバーフローしない範囲であれば1ビットで2倍、2ビットで4倍になる。
  • オーバーフローすると、本来の計算結果をそのビット数では表現できず、異なる値になる。
  • 「符号ビット固定」とは、左端のビットを符号として解釈するという意味であり、「そのビットだけ動かない」という意味ではない。

技術を学ぶ上では、用語だけで理解するのではなく、実際のビット列がどのように変化するのかを確認することが、理解への近道だと改めて感じました。


あとがき

今回この記事を書きながら改めて感じたのは、「言葉の定義」と「実際の動作」は必ずしも一致するとは限らないということです。

特にビット演算のような分野では、用語だけを覚えるよりも、実際にビット列を書いて確認する方が理解が深まります。

私自身も、技術を教える立場として、今後も「なぜそうなるのか」をビット列や図を用いて、できるだけ分かりやすく伝えていきたいと思います。

訪問数 4 回, 今日の訪問数 4回

広告