数字表示

数字表示

整数

补码(Two's complement):

-1 的 8 位表示: 1111 1111
取反加一:       ~1 + 1 = 1111 1110 + 1 = 1111 1111  ✓

为什么用补码:加减法可以用同一套电路(不需要区分正负),且只有一个 0。

溢出的坑:

unsigned char a = 200, b = 100;
unsigned char c = a + b;     // 44(整型提升后截断)

// 有符号溢出是 UB
int x = INT_MAX; x++;         // UB!编译器可以做任何事

整型提升:char/short 参与运算时会先提升为 int,这是很多隐式 bug 的来源。

浮点(IEEE 754)

单精度 float (32 bit): [符号1][指数8][尾数23]
双精度 double (64 bit): [符号1][指数11][尾数52]

值 = (-1)^s × 1.mantissa × 2^(exponent - bias)
bias: float 127, double 1023

特殊值:

值表示
±0指数和尾数全 0(符号位可不同)
±∞指数全 1,尾数全 0
NaN指数全 1,尾数非 0

精度问题:

0.1 + 0.2 == 0.3        // false!实际是 0.30000000000000004
                        // 因为 0.1 无法用二进制精确表示

// 正确比较
fabs(a - b) < 1e-9;

累加误差:大量小浮点数相加时误差累积 → 用 Kahan 求和或更高精度。

NaN 的传播:任何涉及 NaN 的比较都是 false(包括 NaN == NaN)。