IEEE 754双精度浮点数(binary64)使用64位编码:
| 参数 | 单精度(binary32) | 双精度(binary64) |
|---|---|---|
| 总位宽 | 32 | 64 |
| 符号位 | 1 | 1 |
| 指数位宽 | 8 | 11 |
| 尾数位宽 | 23 | 52 |
| Bias | 127 | 1023 |
| 指数范围 | -126 ~ +127 | -1022 ~ +1023 |
| 有效位数 | 24 (含隐含1) | 53 (含隐含1) |
| 十进制精度 | ~7位 | ~16位 |
| 最大值 | ≈3.4×10³⁸ | ≈1.8×10³⁰⁸ |
| 最小规格化数 | ≈1.2×10⁻³⁸ | ≈2.2×10⁻³⁰⁸ |
| 最小非规格化数 | ≈1.4×10⁻⁴⁵ | ≈4.9×10⁻³²⁴ |
双精度53位有效数字意味着:
这对科学计算至关重要。例如,计算天文距离时:
| 类别 | 指数E(11位) | 尾数M(52位) | 十六进制范围 |
|---|---|---|---|
| +0 | 000...0 | 000...0 | 0x00000000_00000000 |
| -0 | 000...0 | 000...0 | 0x80000000_00000000 |
| 非规格化数 | 000...0 | 非0 | 0x00000000_00000001 ~ 0x000FFFFFFFFFFFFF |
| 规格化数 | 001...110 | 任意 | 0x00100000_00000000 ~ 0x7FEFFFFF_FFFFFFFF |
| +∞ | 111...1 | 000...0 | 0x7FF00000_00000000 |
| -∞ | 111...1 | 000...0 | 0xFFF00000_00000000 |
| QNaN | 111...1 | 1xx...x | 0x7FF80000_00000000+ |
| SNaN | 111...1 | 0xx...x(非0) | 0x7FF00000_00000001+ |
//=============================================================
// float64_decoder.sv - IEEE 754 双精度浮点数解码器
// 验证:Verilator --lint-only
//=============================================================
module float64_decoder (
input wire [63:0] fp_in,
output wire sign,
output wire [10:0] exp_field,
output wire [51:0] mant_field,
output wire [10:0] exp_unbiased,
output wire [52:0] mant_full,
output wire is_normal,
output wire is_denorm,
output wire is_zero,
output wire is_infinity,
output wire is_nan
);
assign sign = fp_in[63];
assign exp_field = fp_in[62:52];
assign mant_field = fp_in[51:0];
wire exp_is_zero = (exp_field == 11'b0);
wire exp_is_max = (exp_field == 11'b111_1111_1111);
wire mant_is_zero = (mant_field == 52'b0);
assign is_normal = ~exp_is_zero & ~exp_is_max;
assign is_denorm = exp_is_zero & ~mant_is_zero;
assign is_zero = exp_is_zero & mant_is_zero;
assign is_infinity = exp_is_max & mant_is_zero;
assign is_nan = exp_is_max & ~mant_is_zero;
// 无偏指数: 规格化 E-1023, 非规格化 -1022
assign exp_unbiased = is_normal ? (exp_field - 11'd1023) :
(exp_is_zero ? 11'd1022 : exp_field);
// 完整尾数: 规格化含隐含1
assign mant_full = is_normal ? {1'b1, mant_field} :
{1'b0, mant_field};
endmodule
//=============================================================
// float32_to_float64.sv - 单精度转双精度
// 验证:Verilator --lint-only
//=============================================================
module float32_to_float64 (
input wire [31:0] fp32_in,
output wire [63:0] fp64_out
);
wire sign32 = fp32_in[31];
wire [7:0] exp32 = fp32_in[30:23];
wire [22:0] mant32 = fp32_in[22:0];
wire exp_is_zero = (exp32 == 8'b0);
wire exp_is_max = (exp32 == 8'hFF);
wire mant_is_zero = (mant32 == 23'b0);
// 双精度指数: 单精度指数 + (1023-127) = +896
wire [10:0] exp64_normal = {1'b0, exp32} + 11'd896;
// 非规格化数转双精度需要特殊处理(本实现简化为直接映射)
wire [10:0] exp64 = exp_is_zero ? 11'b0 :
exp_is_max ? 11'b111_1111_1111 :
exp64_normal;
// 尾数: 23位→52位,低位补零
wire [51:0] mant64 = {mant32, 29'b0};
assign fp64_out = {sign32, exp64, mant64};
endmodule
| 部件 | 单精度 | 双精度 | 面积比 |
|---|---|---|---|
| 乘法器 | 24×24 | 53×53 | ~4.9× |
| 加法器 | 24位 | 53位 | ~2.2× |
| 前导零检测 | 24位 | 53位 | ~2.2× |
| 移位器 | 24位 | 53位 | ~2.2× |
| 寄存器堆 | 32×32 | 32×64 | ~2× |
练习1:计算双精度1.0的完整64位十六进制表示。
练习2:双精度能精确表示2⁵³+1吗?为什么?
练习3:实现双精度→单精度的转换模块(含舍入处理)。
练习4:比较单精度和双精度在表示0.1时的相对误差。
✅ 掌握了双精度格式的11位指数与52位尾数
✅ 理解了单精度与双精度在硬件代价上的差异
✅ 实现了双精度解码器和精度转换
✅ 理解了2⁵³整数精度的含义
下一成就:特殊值专家 — 深入NaN/Inf/Denormal