破解到固定的实现

Jos*_*hua 7 javascript

javascript的"Number.toFixed"的默认实现似乎有点破碎.

console.log((8.555).toFixed(2));    // returns 8.56
console.log((8.565).toFixed(2));    // returns 8.57
console.log((8.575).toFixed(2));    // returns 8.57
console.log((8.585).toFixed(2));    // returns 8.59
Run Code Online (Sandbox Code Playgroud)

我需要一种比这更一致的舍入方法.

在8.500和8.660之间的范围内,以下数字不能正确舍入.

8.575
8.635
8.645
8.655
Run Code Online (Sandbox Code Playgroud)

我已经尝试按如下方式修复原型实现,但它只有一半.任何人都可以建议任何可以使其更一致地工作的变化吗?

Number.prototype.toFixed = function(decimalPlaces) {
    var factor = Math.pow(10, decimalPlaces || 0);
    var v = (Math.round(this * factor) / factor).toString();
    if (v.indexOf('.') >= 0) {
        return v + factor.toString().substr(v.length - v.indexOf('.'));
    }
    return v + '.' + factor.toString().substr(1);
};
Run Code Online (Sandbox Code Playgroud)

Jos*_*hua 7

谢谢你的答案.我的实现几乎可以工作,但在某些情况下由于浮点错误没有.

我的函数中的这一行是罪魁祸首:Math.round(this*factor)

(它在Number.prototype上,所以"this"是数字); 8.575*100出现在857.4999999999999,后者又向下舍入.通过将行更改为如下所示进行更正:Math.round(Math.round(this*factor*100)/ 100)

我的整个解决方法现在改为:

Number.prototype.toFixed = function(decimalPlaces) {
    var factor = Math.pow(10, decimalPlaces || 0);
    var v = (Math.round(Math.round(this * factor * 100) / 100) / factor).toString();
    if (v.indexOf('.') >= 0) {
        return v + factor.toString().substr(v.length - v.indexOf('.'));
    }
    return v + '.' + factor.toString().substr(1);
};
Run Code Online (Sandbox Code Playgroud)


小智 5

这是因为浮点错误.

比较(8.575).toFixed(20)(8.575).toFixed(3)想象这个命题:8.575 < real("8.575"),其中真正是创建具有无限精度实数的虚函数.

也就是说,原始数字不符合预期,并且已经引入了不准确性.

我能想到的一个快速的"工作原理"是:乘以1000(或适当的话),得到toFixed(0)它(仍然有一个限制,但这是荒谬的),然后以十进制形式推回.

快乐的编码.