一、 字节序
大端法:低地址存高位
小端法:低地址存低位 (x86_64 默认字节序)
二、通过异或实现 swap
// x mustn't equal to y
void swap(int *x, int *y) {
*y = *x ^ *y;
*x = *x ^ *y; // a ^ (a ^ b) = b
*y = *x ^ *y; // b ^ (a ^ b) = a
}
三、 移位运算
左移 x 位:丢弃高 x 位并左移,低位补 0。
逻辑右移 x 位:无视符号位,丢弃低 x 位并右移,高位补 0。
算术右移 x 位:丢弃低 x 位并右移,高位补符号位。
常见 C 编译器会将 >>
运算符定义为算术右移。
x 很大或为负数时,通常会对 x 进行取模,即取 x 的二进制表示的低
l
o
g
2
w
log_2w
log2w 位,其中
w
w
w 为 x 的位数
四、整数的运算和表示
4.1 整数除法的定义
对应的实数除法截断小数部分的值。
4.2 整数取余的定义
- 当 a 和 b 均为正整数时,取 a 除以 b 的余数。
- 当 a 为正整数,b 为 负整数时,取 a % -b 的值。
- 当 a 为负整数时,取 -(a % b) 的值。
整数 | -5 | -4 | -3 | -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|---|---|---|
%4 值 | -1 | 0 | -3 | -2 | -1 | 0 | 1 | 2 | 3 | 0 | 1 |
特别地,当 a 为正整数且 b 为 2 ^ c (c 为正整数)时,a % b 的值为 a 的低 c 位表示的无符号数。
4.3 整数运算的底层实现
补码和无符号数的加减法和乘法具有位级等价性,除法没有,如 7/-4 值为 -1,但 7u / -4 值为 0。
乘法和除以 2 的幂的除法可以表示成位移和加减法的组合。
五、IEEE 浮点标准
最高位
s
s
s 为符号位,0 为正,1 为负。
紧接着
n
n
n 位小数字段编码尾数
M
M
M,
k
k
k 位阶码字段编码阶码
E
E
E。
最终表示的浮点数数值为
(
−
1
)
s
×
M
×
2
E
(-1)^s\times M\times 2^E
(−1)s×M×2E
32 位单精度:
k
=
8
,
n
=
23
k=8,n=23
k=8,n=23
64 位双精度:
k
=
11
,
n
=
52
k=11,n=52
k=11,n=52
5.1. 无穷大的表示方法
阶码的二进制表示为全 1,尾数的二进制表示为全 0,符号位表示正负。
5.2. 非规格化的情况(阶码的二进制表示为全 0)
此时阶码取值为
1
−
B
i
a
s
1-Bias
1−Bias,其中
B
i
a
s
Bias
Bias 为 127(单精度)或 1023(双精度)。
尾数取值为其二进制表示对应的无符号数
f
f
f。
0.0 的二进制表示是所有位全是 0。
5.3 规格化的情况 (阶码的二进制既不是全 0 也不是全 1)
此时阶码取值为其二进制表示对应的无符号数
e
e
e 减去
B
i
a
s
Bias
Bias,由此产生的
E
E
E 的取值范围是 -126 ~ +127 (单精度)或 -1022 ~ + 1023 (双精度),尾数取值为
1
+
f
1+f
1+f 。
对于正浮点数,从全 0 二进制位一直遍历到除符号位外全 1 的二进制位,其取值分别从 0 到 最小非规格化数,再到最大非规格化数,再到最小规格化数,再到 1,再到最大规格化数,再到无穷大,再到 NaN。