CS:APP 第2章 情報の表現と操作
数をエンコードする方法は3種類
- 符号なしエンコーディング
- 2の補数エンコーディング
- 浮動小数点エンコーディング
上の2つは整数算術に分類される。
整数のコンピュータ算術は多くの基本的な整数算術の性質を満たす。
一方で、浮動小数点算術では結合則が満たされない。
整数表現は比較的狭い範囲の値を正確に表現する。
浮動小数点表現は広い範囲の値をざっくり表現する。
あらゆるコンピュータにはワード・サイズがある。
仮想アドレスはワードに依ってエンコードされる。
ワード・サイズが
Cの規格では符号付き値に対する右シフトが論理シフトなのか算術シフトなのかは決まっていない。
(実際は算術右シフトを行うコンパイラが多い)
整数の表現
Cの規格は各データ型が表現できなければならない最小の値域を定義している。
例えばint
の最小値・最大値は -32767
, 32767
である
int32_t
とかだと -2,147,483,648
~ 2,147,483,647
みたいに非対称
じゃあ INT_MAX
って何処で定義されているのだろうか?処理系?
-> <limits.h>
符号付き数について2の補数表現を仮定するのは、幅広いマシンとコンパイラに関してポータブルである。
Q. 符号付きと符号なしの変換はどういった操作を行っている?
A. ビット表現はそのままで、ビット値の解釈を変えるだけ。(ほとんどの処理系の場合)
unsigned int において
signed int において
一方のオペランドが符号付きで他方が符号なしの演算を行う時、
Cでは符号付きの引数を符号なしへ暗黙的にキャストし、両者が非負と仮定して演算を行う。
ex) -1 < 0U
というのは 4,294,967,295U < 0U
へと変換される
Q. では、short
をunsigned
に変換するとどうなる?
A. まずサイズを変換(2の補数の拡張)し、次に型を変換する
2の補数の拡張は、"算術シフトっぽい"
Q. short
を unsigned char
に変換するとどうなる?
A. まずサイズを変換(切り詰め)し、次に型を変換する
2の補数切り詰めは、算術ビットを気にせず切り詰める
切り詰めはどうやって行うのか?
4bitを3bitに切り詰める場合を考える
符号なし
2の補数
整数演算
剰余加算はアーベル群と呼ばれる数学的な構造を持つ。
すなわち、可換的かつ結合的である。
したがって、x + y - x
のような計算は、中身がどんな値を持とうが常に同じ値を表す。