Skip to content

Instantly share code, notes, and snippets.

@ppazos
Forked from dfkaye/Number.toFixed.js
Created May 8, 2024 04:50
Show Gist options
  • Save ppazos/415b5ab1b674c9b673d080fb3560e3fe to your computer and use it in GitHub Desktop.
Save ppazos/415b5ab1b674c9b673d080fb3560e3fe to your computer and use it in GitHub Desktop.
Updated Number().toFixed() polyfill to add-then-remove the trailing '1' in every case.
// 14 March 2019
// Updated Number().toFixed() polyfill to add-then-remove the trailing '1' in every case.
// see original at https://gist.github.com/dfkaye/e977af36e668aa134c0ce55bab5bb15f
// and at https://dfkaye.wordpress.com/2017/12/06/number-tofixed-rounding-errors-broken-but-fixable/
/*
// fixes blog post solution
;(1.005).toFixed(2) == "1.01" || (function(prototype) {
var toFixed = prototype.toFixed
prototype.toFixed = function(fractionDigits) {
var s = String(this)
var n = ~s.indexOf('.') ? s : s + '1'
return toFixed.call(+n, fractionDigits).slice(0, -1);
}
}(Number.prototype));
*/
/*
// alternate fix found on stackoverflow
// see https://stackoverflow.com/questions/10015027/javascript-tofixed-not-rounding/48356552#48356552
;(1.005).toFixed(2) == "1.01" || (function(prototype) {
var toFixed = prototype.toFixed
prototype.toFixed = function(fractionDigits) {
return this.toLocaleString(0, {
minimumFractionDigits: fractionDigits,
maximumFractionDigits: fractionDigits
})
}
}(Number.prototype));
*/
// run the rest of this to see results in console...
function test({fraction, size}) {
// Happy side-effect: `toString()` removes trailing zeroes.
var f = fraction.toString()
var fixed = f.split('.')[1].length - 1
// All this to create the expectedFraction message...
var last = Number(f.charAt(f.length - 1))
var digit = Number(f.charAt(f.length - 2))
last >= 5 && (digit = digit + 1)
var expectedFraction = f.replace(/[\d]{2,2}$/, digit)
var map = Array(size).fill(0)
.map(function(v, i) {
return i + 1
})
.filter(function(v) {
// Compares 1.015 to 1.0151 b/c fixing by more than one decimal place rounds correctly.
var n = v + Number(fraction) // number 1.015
var s = n.toFixed(fixed) // string "1.015"
var s1 = Number(n + '1').toFixed(fixed) // string "1.0151"
console.log(s, s1);
return s != s1
})
.map(function(v, i) {
console.log(v)
return {
given: (v + Number(fraction)).toString(),
expected: (Number(v.toFixed(0)) + Number(expectedFraction)).toString(),
actual: Number(v + fraction).toFixed(fixed)
}
});
console.log(map);
return map;
}
test({ fraction: .015, size: 128 }).forEach(function(item) {
console.log(item)
});
;(function () {
;(1.005).toFixed(2) == "1.01" || (function(prototype) {
var toFixed = prototype.toFixed
prototype.toFixed = function(fractionDigits) {
var s = String(this)
var n = ~s.indexOf('.') ? s : s + '1'
return toFixed.call(+n, fractionDigits).slice(0, -1);
}
/*
prototype.toFixed = function(fractionDigits) {
return this.toLocaleString(0, {
minimumFractionDigits: fractionDigits,
maximumFractionDigits: fractionDigits
})
}*/
}(Number.prototype));
});
console.log(
(1.005).toFixed(2)
)
console.log(
(1.005).toFixed(4)
)
console.log(
(1.0149999).toFixed(2)
)
console.log(
(1.0149999).toFixed(4)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment