我有以下虚拟测试脚本:
function test() {
var x = 0.1 * 0.2;
document.write(x);
}
test();
这将打印结果0.020000000000000004,而它应该只打印0.02 (如果您使用计算器)。据我所知,这是由于浮点乘法精度的错误造成的。
有没有人有好的解决方案,让我在这种情况下得到正确的结果,0.02?我知道像toFixed或四舍五入这样的函数是另一种可能,但我真的希望打印出完整的数字,而不是任何剪切和舍入。只是想知道你们中有没有什么好的,优雅的解决方案。
当然,否则我会舍入到10位左右。
发布于 2010-08-09 20:30:58
我能做些什么来避免这个问题?
这取决于你正在做什么类型的计算。
请注意,第一点仅适用于您确实需要特定的精确小数行为的情况。大多数人并不需要它,他们只是对他们的程序在1/10这样的数字下不能正常工作感到恼火,而没有意识到如果1/3出现同样的错误,他们甚至不会眨眼。
如果第一点确实适用于您,请使用BigDecimal for JavaScript,它一点也不优雅,但实际上解决了问题,而不是提供不完美的解决方法。
发布于 2010-09-05 07:00:13
我喜欢Pedro Ladaria的解决方案,并使用类似的解决方案。
function strip(number) {
return (parseFloat(number).toPrecision(12));
}与Pedros解决方案不同,这将向上舍入0.999...repeating,并精确到最低有效数字上的加/减1。
注意:在处理32位或64位浮点数时,您应该使用toPrecision(7)和toPrecision(15)以获得最佳结果。有关原因的信息,请参阅this question。
发布于 2013-09-20 10:55:53
对数学有兴趣的人:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
推荐的方法是使用校正因子(乘以适当的10次方,以便在整数之间进行运算)。例如,在0.1 * 0.2的情况下,校正因子为10,并且您正在执行以下计算:
> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> (x * cf) * (y * cf) / (cf * cf)
0.02一个(非常快速的)解决方案类似于:
var _cf = (function() {
function _shift(x) {
var parts = x.toString().split('.');
return (parts.length < 2) ? 1 : Math.pow(10, parts[1].length);
}
return function() {
return Array.prototype.reduce.call(arguments, function (prev, next) { return prev === undefined || next === undefined ? undefined : Math.max(prev, _shift (next)); }, -Infinity);
};
})();
Math.a = function () {
var f = _cf.apply(null, arguments); if(f === undefined) return undefined;
function cb(x, y, i, o) { return x + f * y; }
return Array.prototype.reduce.call(arguments, cb, 0) / f;
};
Math.s = function (l,r) { var f = _cf(l,r); return (l * f - r * f) / f; };
Math.m = function () {
var f = _cf.apply(null, arguments);
function cb(x, y, i, o) { return (x*f) * (y*f) / (f * f); }
return Array.prototype.reduce.call(arguments, cb, 1);
};
Math.d = function (l,r) { var f = _cf(l,r); return (l * f) / (r * f); };在这种情况下:
> Math.m(0.1, 0.2)
0.02我绝对推荐使用像SinfulJS这样的经过测试的库
https://stackoverflow.com/questions/1458633
复制相似问题