这是我尝试修复 JavaScript toFixed() 函数...
任何意见、想法、对可能错误的更正都非常感谢!
- 修复浮点误差(例如 (35.355).toFixed(2) = 35.36,不是 35.35)
- 没有额外的大型库
- 功能全面(人类可读)
- 模仿固定/即输出完全相同(尽管对浮点不正确或过程进行了修正)
这是我的尝试 -> 下面的演示(请参阅控制台日志)
Number.prototype.toFixed = function(fractionDigits) {
var digits = parseInt(fractionDigits) || 0;
var num = Number(this);
if( isNaN(num) ) {
return 'NaN';
}
var sign = num < 0 ? -1 : 1;
if (sign < 0) { num = -num; }
digits = Math.pow(10, digits);
num *= digits;
num = Math.round( Math.round(num * Math.pow(10,12)) / Math.pow(10,12) );
var finalNumber = sign * num / digits;
// add 0 after last decimal number (not 0) for as many as requested (fractionDigits)
// in else case, check if requested digits exceed actual, then add 0 (avoid 10.1 for toFixed(2))
if(fractionDigits > 0 && finalNumber.toString().indexOf('.') == -1){
// check that .00 is present
finalNumber = finalNumber.toString() + '.' + '0'.repeat(fractionDigits);
} else if(fractionDigits > finalNumber.toString().split('.')[1]?.length){
finalNumber = finalNumber.toString() + '0'.repeat((fractionDigits - finalNumber.toString().split('.')[1]?.length));
}
return finalNumber.toString(); // tofixed returns as string always, do the same
}
console.log('(35.355).toFixed(2)', (35.355).toFixed(2));
console.log('(35.1).toFixed(2)', (35.1).toFixed(2));
console.log('(35).toFixed(2)', (35).toFixed(2));
Number.prototype.toFixed = function(fractionDigits) {
//function toFixed(numberInput, fractionDigits){
var digits = parseInt(fractionDigits) || 0;
var num = Number(this);
if( isNaN(num) ) {
return 'NaN';
}
var sign = num < 0 ? -1 : 1;
if (sign < 0) { num = -num; }
digits = Math.pow(10, digits);
num *= digits;
num = Math.round( Math.round(num * Math.pow(10,12)) / Math.pow(10,12) );
var finalNumber = sign * num / digits;
// add 0 after last decimal number (not 0) for as many as requested (fractionDigits)
if(fractionDigits > 0 && finalNumber.toString().indexOf('.') == -1){
// check that .00 is present
finalNumber = finalNumber.toString() + '.' + '0'.repeat(fractionDigits);
} else if(fractionDigits > finalNumber.toString().split('.')[1]?.length){
finalNumber = finalNumber.toString() + '0'.repeat((fractionDigits - finalNumber.toString().split('.')[1]?.length));
}
return finalNumber.toString(); // tofixed returns as string always, do the same
}
console.log('post-fix | (35.355).toFixed(2)', (35.355).toFixed(2));
console.log('post-fix | (35.1).toFixed(2)', (35.1).toFixed(2));
console.log('post-fix | (35).toFixed(2)', (35).toFixed(2));
最佳答案
如果是我,我可能会采用这种字符串操作方法:
Number.prototype.toFixed = function(fractionDigits) {
var number = String(this);
var digits = fractionDigits || 0, length;
if(digits < 0 && digits > 100)
throw 'RangeError: toFixed() digits argument must be between 0 and 100';
var decimal = number.match(/(?<=\.)(\d*)/g);
var factor = Math.pow(10, digits);
if (decimal && decimal[0].length >= digits)
return String(Math.round(Number(number + '1') * factor) / factor);
else {
var length = digits - (decimal ? decimal[0].length : 0);
var delimiter = number.includes('.') || !length ? '' : '.';
return String(number) + delimiter + '0'.repeat(length);
}
}
function test() {
console.log((-35.555).toFixed(2))
console.log((-35.35).toFixed(2))
console.log((-35.9).toFixed(2))
console.log((-35).toFixed(2))
}
注意:
- 我认为您不会在
toFixed
中遇到字符串因为它不会被它触发,所以你不需要isNaN
检查一下。 - 当参数小于 0 或大于 100 时提前捕获。这应该会抛出与原始错误类似的错误。
输出:
关于javascript - 用适当的替换覆盖 toFixed() 以修复浮点错误 javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72052086/