You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

相等十进制值转浮点数后不匹配,单元测试失败原因咨询

问题原因解析

这个测试失败的核心原因在于二进制浮点数的固有局限性,以及rust_decimal内部存储与转换的细节,具体分为三点:

1. 十进制1.539无法被二进制浮点数精确表示

f64是基于二进制的浮点类型,仅能精确表示分母为2的幂的分数(比如0.5=1/2、0.25=1/4)。而1.539的分数形式是1539/1000,分母1000包含因子5³,无法被2的幂整除,因此转成f64时只能存储最接近它的二进制近似值,而非精确值。

2. 数值相等的Decimal实例,内部存储精度可能不同

虽然assert_eq!(dec!(1.539), total2)通过了,但rust_decimal的相等判断是基于数值等价,而非内部存储的完全一致:

  • total1是通过val1 * coef + val2直接计算得到的,内部存储为1539 × 10^-3(精确的十进制1.539)。
  • total2是先将total1_f(total1的f64近似值)转回Decimal,再经过/coef * coef运算得到的。这个过程中,Decimal可能会以更高精度存储数值(比如带有更多尾零,或存储为与1539 ×10^-3等价但缩放因子不同的形式)。

3. 不同的Decimal内部表示,转f64时会产生不同的二进制近似

当把这两个数值等价的Decimal转成f64时,由于内部存储的数字位数和缩放因子不同,转换过程中的舍入计算会产生细微差异:

  • 对于total1(1539 ×10^-3),转换是计算1539 ÷ 1000的二进制近似。
  • 对于total2(比如可能是1539000000000000 ×10^-16),转换是计算1539000000000000 ÷ 10^16的二进制近似。

这两个计算的结果在二进制浮点数中会有极细微的比特模式差异,最终导致assert_eq!(total1_f, total2_f)失败。


内容的提问来源于stack exchange,提问作者andigor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 03:34:58