提问人:Kzqai 提问时间:5/23/2019 最后编辑:Kzqai 更新时间:5/23/2019 访问量:126
在完全使用 javascript 的 Web 堆栈中,从十进制货币源转换时如何避免浮点错误?
In a fully javascript web stack, how can floating point errors be avoided when converting from a currency source in decimal?
问:
我最近不得不设计一个完全使用javascript,express.js,REST apis,完整节点/浏览器js堆栈的资金处理应用程序。不幸的是,该应用程序处理了各种自定义计算,例如平均结果。当然,在对结果求平均值时,浮点加法和除法会发挥作用。因此,我会得到大约 0.12(12 美分!
从理论上讲,我了解处理浮点数的推荐选项:
- 以整数计算
- 圆
- 在其他位置使用十进制数据类型
整数换货币的方法很好,这是有道理的,但不幸的是,如果请求以十进制形式传入,那么最初将浮点数转换为整数的某种计算仍然必须发生,并且仍然保留了出错的可能性。
因此,假设有一个请求被添加到美元价值列表中。
以干净的整数单位使用它会很好,但要到达那里需要先乘以 100,我怀疑这会导致整套错误随之而来。44.67
那么,在 javascript 中,处理十进制或美元请求之间的平滑转换以及避免浮点错误的计算的过程是什么?
在这种情况下,是否需要数据库,并且只需将值作为字符串传递到数据库中?或者有没有办法在 javascript 中将“无损”转换为整数?还是在处理金钱并要求准确性时有其他技术?
答:
1赞
Eric Postpischil
5/23/2019
#1
问题中描述的问题中的潜在错误来源包括:
- 输入值非常大,无法乘以 100 并四舍五入到最接近的整数而不会出错。(这需要大约 1013 或更大的输入值,因此除非数据涉及数万亿美元,否则不太可能。
- 执行的计算可能会导致值过大,从而导致出现舍入错误。
- 输入中提到的“自定义计算”包括具有舍入误差的内容,即使值是小整数。例如,提到了“平均”,并且 1 美分、1 美分和 2 美分的平均值不能在没有舍入误差的情况下以二进制浮点计算,因为 4/3 是不可表示的。此外,“自定义计算”可能包括对数、概率分布的评估、积分以及初等算术以外的其他数学。
- 代码中可能存在错误。
那么在 [JavaScript] 中,处理十进制或美元请求之间的平滑转换以及避免浮点错误的计算的过程是什么?
关于前者,如果 x 是以十进制输入字符表示的数字,小数点后最多两位数,并且不太大(如上所述),并且是将该输入正确转换为 JavaScript 的结果,那么结果正好是 100x。没有净舍入误差。任何计算错误的根源都在别处。x
Number
Math.round(100*x)
评论
Math.round(value * 100)
.
parseInt()