Am I missing something here?
var someNumber = 123.456; someNumber = someNumber.toFixed(2); alert(typeof(someNumber)); //alerts string Why does .toFixed() return a string?
I want to round the number to 2 decimal digits.
Am I missing something here?
var someNumber = 123.456; someNumber = someNumber.toFixed(2); alert(typeof(someNumber)); //alerts string Why does .toFixed() return a string?
I want to round the number to 2 decimal digits.
Number.prototype.toFixed is a function designed to format a number before printing it out. It's from the family of toString, toExponential and toPrecision.
To round a number, you would do this:
someNumber = 42.008; someNumber = Math.round( someNumber * 1e2 ) / 1e2; someNumber === 42.01; // if you need 3 digits, replace 1e2 with 1e3 etc. // or just copypaste this function to your code: function toFixedNumber(num, digits, base){ const pow = Math.pow(base ?? 10, digits); return Math.round(num*pow) / pow; } Why isn't this function included in the JavaScript's standard library? Because floating point numbers are hard! Many decimal numbers cannot be directly represented by base-two floats – that's why 0.09 + 0.01 !== 0.1 but 0.09999999999999999. If developers were given a tool which is supposed to round floats to decimal places, they'd (wrongly) assume that it really returns a decimal number, when it in fact returns the closest representable double-precision base-two float.
type Number. The thing is that +(anyValue) always returns a number – eg. +("45") returns 45, +(new Number(42)) returns 42. It's kinda like strong-typing the function. If you make a habit of it, you can avoid a lot of bugs :)someNumber = Math.round( 42.008 * 1e2 ) / 1e2; is not 42.01, it is ~42.0099999999999980. Reason: The number 42.01 does not exists and is rounded to the nearest existing number. btw, proof numbers by toPrecision(18) to print it with all relevant digits.I've solved this problem by changing this:
someNumber = someNumber.toFixed(2) ...to this:
someNumber = +someNumber.toFixed(2); However this will convert the number to a string and parse it again, which will have a significant impact on performance. If you care about performance or type safety, check the the other answers as well.
someNumber = Math.round(someNumber * 1e2) / 1e2! See my answer for a more generalized way.Math.round(someNumber * 1e2) / 1e2 is very easy to remember. JavaScript is such fun 😁🤣😜It returns a string because 0.1, and powers thereof (which are used to display decimal fractions), are not representable (at least not with full accuracy) in binary floating-point systems.
For example, 0.1 is really 0.1000000000000000055511151231257827021181583404541015625, and 0.01 is really 0.01000000000000000020816681711721685132943093776702880859375. (Thanks to BigDecimal for proving my point. :-P)
Therefore (absent a decimal floating point or rational number type), outputting it as a string is the only way to get it trimmed to exactly the precision required for display.
toFixed is a formatting function, which has a sole purpose of converting a number to a string, formatting it using the specified number of decimals. The reason it returns a string is because it's supposed to return a string, and if it was named toStringFixed instead, OP wouldn't be surprised at the results. The only issue here is that OP expected it to work like Math.round, without consulting JS reference.Why not use parseFloat?
var someNumber = 123.456; someNumber = parseFloat(someNumber.toFixed(2)); alert(typeof(someNumber)); //alerts number Because its primary use is displaying numbers? If you want to round numbers, use Math.round() with apropriate factors.
'42' is a number...which it's not. Just because a string happens to contain digits only does not make it a number. This isn't PHP. :-PHere's a slightly more functional version of the answer m93a provided.
const toFixedNumber = (toFixTo = 2, base = 10) => num => { const pow = Math.pow(base, toFixTo) return +(Math.round(num * pow) / pow) } const oneNumber = 10.12323223 const result1 = toFixedNumber(2)(oneNumber) // 10.12 const result2 = toFixedNumber(3)(oneNumber) // 10.123 // or using pipeline-operator const result3 = oneNumber |> toFixedNumber(2) // 10.12 To supply an example of why it has to be a string:
If you format 1.toFixed(2) you would get '1.00'.
This is not the same as 1, as 1 does not have 2 decimals.
I know JavaScript isn't exactly a performance language, but chances are you'd get better performance for a rounding if you use something like: roundedValue = Math.round(value * 100) * 0.01
For others like me that happen upon this very old question, a modern solution:
const roundValue = (num, decimals = 2) => { let scaling = 10 ** decimals; return Math.round((num + Number.EPSILON) * scaling) / scaling; } You should use it like below.
var someNumber: number = 0.000000; someNumber = Number(someNumber.toFixed(2)) Why not * the result by 1 i.e
someNumber.toFixed(2) * 1
Be careful using toFixed() and Math.round(), they can produce unexpected results due to the floating point number system:
function toFixedNumber(num, digits, base){ var pow = Math.pow(base||10, digits); return Math.round(num*pow) / pow; } console.log(toFixedNumber(130.795, 2, 10)); // 130.79 (incorrect) console.log(toFixedNumber(100.795, 2, 10)); // 100.8 console.log(+130.795.toFixed(2)); // 130.79 (incorrect) console.log(+100.795.toFixed(2)); // 100.8 I recommend using Lodash's _.round() function: https://lodash.com/docs/4.17.15#round
_.round(130.795, 2); // 130.8