Terraform 十进制小数转百分比时出现浮点数计算精度异常问题
Terraform小数转百分比精度偏差问题解决
问题复现
使用Terraform执行十进制小数转百分比的乘法计算时,部分结果符合预期,部分结果存在明显精度偏差,该问题在Terraform 1.1.4、1.2.3版本均可稳定复现,控制台执行示例如下:
$ terraform console > 0.2 * 100 20 > 0.01 * 100 0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 > 0.005 * 100 0.49999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999996
直接调用ceil或floor取整函数无法解决该问题:浮点数误差方向不固定,统一向上/向下取整会将本应得到的1取为0,或将0.5取为1,不符合业务预期。
问题根因
该现象不是Terraform的版本bug,是二进制浮点数的通用固有特性:Terraform的number类型遵循IEEE754浮点数标准,0.01、0.005这类十进制有限小数无法被二进制浮点数精确表示,存储值本身就是近似值,乘法运算会放大该误差,最终输出接近但略小于/略大于目标值的结果。
可行解决方案
根据实际业务需求选择对应方案即可:
- 方案1:固定精度格式化(通用首选)
利用Terraform内置format函数做固定精度转换,函数会自动识别浮点数的微小偏差,输出符合预期的结果。如果需要整数类型的百分比值,写法如下:
如果需要保留指定位数的小数百分比,修改格式化占位符即可,例如保留2位小数就使用# 0.01 * 100 会返回正确数值1,不会出现0.999...的误差结果 percentage = tonumber(format("%.0f", your_decimal * 100))%.2f作为占位符。 - 方案2:整数运算规避误差(适合精度固定场景)
如果业务中使用的小数有明确的最大小数位数,可以先将小数放大为整数后再做运算,从根源上规避浮点数计算误差。例如原始小数最多保留3位小数,要转换为百分比(乘以100),可先放大1000倍转整数运算,最后缩放回目标精度:
注意整数缩放的倍数需要根据业务实际的最大小数位调整,避免截断有效数字。# 以0.005为例:乘1000取整得5,乘100得500,除以1000得到正确值0.5 percentage = (floor(your_decimal * 1000) * 100) / 1000
内容的提问来源于stack exchange,提问作者JamesFrost
相关产品推荐
相关产品推荐

