Ada中浮点字面量与浮点变量运算的舍入结果差异问题
Ada浮点数舍入结果差异原因解答
核心原因
这一差异是编译期常量运算精度与运行期变量运算精度的规则不同导致的,和变量的存储截断特性直接相关,具体说明如下:
- 常量表达式的计算特性
直接调用float'rounding(8.9 / 0.2)时,8.9和0.2属于Ada的Universal_Real通用实数值常量,并未默认绑定Float类型。编译器在编译阶段计算该常量表达式时,会采用远高于单精度Float的精度(通常为处理器支持的扩展双精度格式)完成运算,此时两个数值的近似误差足够小,除法结果非常接近真实的44.5,按照远离零的舍入规则就会得到45。即便手动给常量增加Float强转,多数编译器的常量折叠逻辑仍会保留更高精度的中间计算结果,不会提前截断到单精度。 - 变量存储的精度截断特性
把8.9、0.2赋值给Float类型的变量时,两个值会立刻被舍入/截断到IEEE 754单精度浮点数的表示范围:- 二进制浮点数本身无法精确表示十进制的0.2,单精度下的存储值比真实0.2略大
- 8.9的单精度存储值比真实8.9略小
两个已经存在精度损失的单精度值做除法时,得到的结果会比44.5略小(通常为44.499996左右),此时触发舍入规则就会向下取到44。
可通过打印变量
a、b的精确十进制表示,以及a/b的完整运算结果验证上述误差情况。
内容的提问来源于stack exchange,提问作者The Iron Duckling
相关产品推荐
相关产品推荐

