算術演算と精度
8 ビットの 2 の補数で表した −8(11111000)を算術右シフトで 1 ビットずらすと? 論理右シフトなら?
算術右シフトは 11111100(−4)、論理右シフトは 01111100(124)。
算術右シフトは空いた左端に元の符号ビット(1)を入れるので、負の数のまま 1/2 になる。 論理右シフトは左端に必ず 0 を入れるので、符号付きの数として見ると値が変わってしまう。
x を 10 倍する計算を、シフトと加算だけで行うには?
x を左へ 3 ビットシフトした値(8x)と、左へ 1 ビットシフトした値(2x)を足す。
10x = 8x + 2x である。あるいは、x を 2 ビット左シフトして 4x を作り、x を足して 5x にしてから 1 ビット左シフトしてもよい。
値がほぼ等しい 2 数の引き算で起きる誤差と、絶対値が大きく違う 2 数の足し算で起きる誤差は、それぞれ何か?
前者は桁落ち、後者は情報落ち。
桁落ちは、上位の桁が打ち消し合って有効数字の桁数が減る現象。 情報落ちは、小さい方の数の下位の桁が、大きい方の数の仮数部に収まりきらずに捨てられる現象である。
2 進数を左へ 1 ビットシフトすると 2 倍、右へ 1 ビットシフトすると 1/2 になる。符号を保つのが算術シフト、保たないのが論理シフトである。有限のビットで計算するため、表現範囲を超えるあふれと、丸め・打切り・桁落ち・情報落ちの誤差が生じる。
演算で生じる誤差・異常の一覧
| 名称 | どんなときに起きるか | 例・対策 |
|---|---|---|
| オーバーフロー | 計算結果が、表現できる範囲(最小値〜最大値)を超える | 8 ビットの 2 の補数で 100 + 100(範囲は 127 まで) |
| アンダーフロー | 浮動小数点数で、結果の絶対値が表現できる最小値より小さい | 0 に近すぎて 0 とみなされる |
| 丸め誤差 | 表現できる桁数に合わせて、下位の桁を四捨五入・切り上げ・切り捨てする | 0.1 を 2 進数の有限桁で表す |
| 打切り誤差 | 無限に続く計算(級数・反復計算)を途中で打ち切る | 円周率の級数を 10 項で止める |
| 桁落ち | 値がほぼ等しい 2 数の減算 | 式を変形して減算を避ける |
| 情報落ち | 絶対値が大きく違う 2 数の加減算 | 絶対値の小さい数どうしから先に足す |
ビット列を左右にずらす演算で、2 進数では左へ 1 ビットで 2 倍、右へ 1 ビットで 1/2 になる。右シフトの端数は小さい方へ丸まり、負の数を算術右シフトすると −7 → −4 のように 0 から遠ざかる側になる。
| 種類 | 空いたビットに入れる値 | 用途 |
|---|---|---|
| 論理シフト | 左右どちらでも 0 | 符号なしの数、ビットパターンの操作 |
| 算術シフト | 右シフトでは符号ビットと同じ値、左シフトでは 0 | 符号付き(2 の補数)の数の乗除算 |
算術シフトでは符号ビットそのものは動かさない扱いと、符号ビットを含めてずらす扱いがあり、 試験問題では問題文の定義に従う。算術左シフトで符号ビットと異なる値が押し出される(符号が変わる)と、オーバーフローである。
表現できる範囲とあふれ
Section titled “表現できる範囲とあふれ”n ビットの符号なし整数は 0 〜 2ⁿ − 1、2 の補数は −2ⁿ⁻¹ 〜 2ⁿ⁻¹ − 1 を表せる。 範囲を超えるとオーバーフローになり、たとえば 8 ビットの 2 の補数で 127 + 1 を計算すると 10000000(−128)になってしまう。 正の数どうしの和が負になる、負の数どうしの和が正になる、という形で検出できる。
浮動小数点数の誤差
Section titled “浮動小数点数の誤差”浮動小数点数は仮数部のビット数が有限なので、ほとんどの実数を近似値でしか表せない。
- 丸め誤差 — 表せない桁を四捨五入・切り捨て・切り上げしたことで生じる差
- 打切り誤差 — 本来は無限に続く計算を有限回で止めたことで生じる差。丸めとは原因が違う
- 桁落ち — 例: 1.2345 と 1.2344(有効数字 5 桁)の差は 0.0001 で、有効数字は 1 桁しか残らない
- 情報落ち — 例: 有効数字 4 桁で 1000 + 0.1 を計算すると 1000.1 は 4 桁に収まらず、結果は 1000 のまま
情報落ちの対策として、多数の数を合計するときは絶対値の小さい順に足す。 小さい数どうしを先に足して大きくしておけば、大きい数に足したときに捨てられにくい。
単精度と倍精度 — 倍精度は仮数部が長い(IEEE 754 で単精度 23 ビット、倍精度 52 ビット)ため、 丸め誤差・桁落ち・情報落ちの影響を小さくできる。
試験での注意
Section titled “試験での注意”- 「論理シフト」と「算術シフト」の主な違いは、右シフトで左端に入れる値(0 か符号ビットか)。符号ビットを固定する定義では、左シフトでも符号ビットが保たれる
- 桁落ちと情報落ちを取り違えやすい。「ほぼ等しい数の減算」が桁落ち、「大きさが違う数の加算」が情報落ち
- 打切り誤差は「計算を途中でやめる」ことによる誤差で、数値の丸め(端数処理)とは別物
なぜそうなっているのか
Section titled “なぜそうなっているのか”シフトで乗除算ができるのは、位取り記数法では 1 桁ずらすと値が基数倍になるからである(10 進数で 1 桁左へずらすと 10 倍になるのと同じ)。 シフトは乗算回路より単純で速いため、2 の累乗の乗除算や、シフトと加算を組み合わせた乗算に使われる。