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)
谢谢你的答案.我的实现几乎可以工作,但在某些情况下由于浮点错误没有.
我的函数中的这一行是罪魁祸首: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)它(仍然有一个限制,但这是荒谬的),然后以十进制形式推回.
快乐的编码.
| 归档时间: |
|
| 查看次数: |
4700 次 |
| 最近记录: |