IEEE754浮点数规范复习
在IEEE754中,不同精度的浮点数各部分位宽如下表所示
| 格式 | 总位数 | 阶码位数 | 尾数位数 |
|---|---|---|---|
| 半精度 | 16 | 5 | 10 |
| 单精度 | 32 | 8 | 23 |
| 双精度 | 64 | 11 | 52 |
| 四倍精度 | 128 | 15 | 112 |
规格化数和非规格化数
规格化数
阶码不允许出现全0或者全1的情况,指数在阶码中的编码形式为偏移码,偏移量为\(2^{k - 1} - 1\)
非规格化数
- 阶码全1
- 尾数全0,表示∞
- 尾数非0,表示NaN(Not a number)
- 阶码全0
- 尾数全0,表示浮点数0
- 尾数非0,指数仍然为\(1 - offset\),底数表示\(0.M\),注意此时不同于规格化数默认小数点左侧为1
- 阶码全1
C语言转换实现
该方法中需要注意的是非规格化数0.···的转化,该部分代码将fraction部分的编码持续左移,直到最高位1超出10位的位宽,其目的是重新构造规格化表示的小数,所以可以看到exponent也在同步递减来保持原来的指数
我们知道在阶码全0的非规格化数中存在一种‘合法’表示的浮点数,该浮点数的小数部分前不补1,同时阶码部分仍视为\(1 - offset\)(原因是用于和最小的规格化浮点数平滑的连接)
1 |
|
关于C语言强制类型转换的思考
C语言的强制类型转换在两方面存在差异:整型之间的转化、整型和浮点数之间的转换
有符号整数/无符号整数的转换
在整型有无符号的转换之间,编译器并不会改变变量的底层编码,仅改变编码的解读方式
1 | int main() { |
输出unsigned x = 4294967295, signed x = -1,这两个数底层编码相同。但情况在浮点数/整数之间不同
整型/浮点数的转换
如果将整数/浮点数之间相互转换,C语言编译器会改变相应变量的底层编码,即补码和IEEE754浮点数两种编码方式之间的转换。同时需要注意的是C语言中不支持浮点数位运算,因此在上述示例代码中我采用指针的强制类型转换形式来保留编码格式