javascript - 修正JavaScript中浮点精度错误的算法

标签 javascript algorithm floating-point rounding precision

您可以找到很多关于浮点精度错误以及如何在 Javascript 中避免它们的信息,例如 "How to deal with floating point number precision in JavaScript?" ,他们通过将数字四舍五入到固定的小数位数来处理问题。

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

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

enter image description here

(请参阅此 Fiddle 以了解我徒劳的尝试) 代码:

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

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

最佳答案

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

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

如果我没记错的话(我不经常使用 JavaScript),JavaScript 使用 IEEE-754 64 位二进制。对于这种格式,众所周知,任何 15 位十进制数字都可以无错误地转换为这种二进制浮点格式并返回。因此,如果原始输入是最多 15 位有效数字的十进制数字,并且它被转换为 64 位二进制 float (并且没有对其执行可能引入额外错误的其他操作),并且您格式化二进制浮点值作为 15 位十进制数字,你将得到原始数字。

生成的十进制数字可能有尾随零。不可能知道(仅从二进制浮点值)它们是否在原始数字中。

关于javascript - 修正JavaScript中浮点精度错误的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47634766/

相关文章:

c# - 如何让 InvariantCulture 将逗号识别为小数点分隔符?

javascript - 通过嵌套对象id获取对象的长度?

javascript - 在事件上运行 javascript 文件

algorithm - 使用最少的更改将树转换为堆

algorithm - 动态规划的递归求解

algorithm - 快速平均平方差函数

javascript - Lodash _.filter 函数只能满足一个条件

javascript - cy.fit() 不会立即工作,它需要超时来适应图表。 Cytoscape.js

Python浮点到字符串,只有 "dotted notation"?

python - 在 Python 中比较两个 float 是否相等