繁体   English   中英

纠正JavaScript中浮点精度错误的算法

[英]Algorithm to correct the floating point precision error in JavaScript

您可以找到许多有关浮点精度错误以及如何在Javascript中避免它们的信息,例如“如何处理JavaScript中的浮点数精度?”。 ,他们只需将数字四舍五入到固定的小数位数即可解决问题。

我的问题略有不同 ,我从后端获取数字(有些带有舍入错误),并希望显示时没有错误。

当然,我可以使用value.toFixed(X)将数字四舍五入到小数点后的位数。 问题是数字的范围可以从0.000000001到1000000000,所以我永远不能确定多少位数是有效的。

在此处输入图片说明

(有关我的不成功尝试,请参见此小提琴 )代码:

var a = 0.3;
var b = 0.1;
var c = a - b; // is 0.19999999999999998, is supposed to be 0.2
// c.toFixed(2)  = 0.20 
// c.toFixed(4)  = 0.2000 
// c.toFixed(5)  = 0.200000


var d = 0.000003;
var e = 0.000002;
var f = d - e; // is 0.0000010000000000000002 is supposed to be 0.000001
// f.toFixed(2)  = 0.00 
// f.toFixed(4)  = 0.0000 
// f.toFixed(5)  = 0.000001

var g = 0.0003;
var h = 0.0005;
var i = g + h; // is 0.0007999999999999999, is supposed to be 0.0008
// i.toFixed(2)  = 0.00 
// i.toFixed(4)  = 0.0008 
// i.toFixed(5)  = 0.000800

我的问题是,如果有任何算法,可以智能地检测出多少个小数位是合理的,并相应地四舍五入数字?

当十进制数字四舍五入为二进制浮点数时,仅从结果中就无法知道原始数字是多少或有多少有效数字。 无限多个小数将舍入到相同的结果。

但是,舍入误差是有界的。 如果知道原始数字最多具有一定数目的数字,则只有具有该数字数目的十进制数字才是候选数字。 如果这些候选者中只有一个与二进制值的差异小于最大舍入误差,则该候选者必须是原始数字。

如果我没记错(我不经常使用JavaScript),则JavaScript使用IEEE-754 64位二进制文​​件。 对于这种格式,众所周知任何15位十进制数字都可以转换为该二进制浮点格式,然后再无错误地返回。 因此,如果原始输入是一个最多包含15个有效数字的十进制数字,然后将其转换为64位二进制浮点数(并且未对其执行任何其他操作,可能会引入其他错误),则可以格式化二进制浮点值是一个15位十进制数字,您将拥有原始数字。

结果十进制数字可能带有尾随零。 无法(仅从二进制浮点值知道)它们是否在原始数字中。

由于Eric的回答,一种衬板解决方案:

const fixFloatingPoint = val => Number.parseFloat(val.toFixed(15))

fixFloatingPoint(0.3 - 0.1) // 0.2
fixFloatingPoint(0.000003 - 0.000002) // 0.000001
fixFloatingPoint(0.0003 + 0.0005) // 0.0008

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM