As stated in the docs, toFixed() does round when necessary. The rounding behavior is to round in the range -.5 < x <= +.5 of the digit.
The strange behavior you're observing is consistent with the note in the docs linked above:
Floating point numbers cannot represent all decimals precisely in binary which can lead to unexpected results such as 0.1 + 0.2 === 0.3 returning false .
In other words, this is a classic case of floating point precision loss - a problem you'll encounter in virtually any language. If you observe the full outputs of a and b you'll see that a == 0.075 and b == 0.07500000000000001 due to floating point precision - and thus given these values it is consistent with the defined rounding behavior to round a to .07 and b to .08.
Videos
What is the syntax for the toFixed() method?
Is it possible to use toFixed() on non-numeric values?
What if I pass a negative argument to toFixed()?
As stated in the docs, toFixed() does round when necessary. The rounding behavior is to round in the range -.5 < x <= +.5 of the digit.
The strange behavior you're observing is consistent with the note in the docs linked above:
Floating point numbers cannot represent all decimals precisely in binary which can lead to unexpected results such as 0.1 + 0.2 === 0.3 returning false .
In other words, this is a classic case of floating point precision loss - a problem you'll encounter in virtually any language. If you observe the full outputs of a and b you'll see that a == 0.075 and b == 0.07500000000000001 due to floating point precision - and thus given these values it is consistent with the defined rounding behavior to round a to .07 and b to .08.
The problem you are encountering is not specific to JavaScript, it is common to computing in general.
Both these arithmetic calculations have the same result – 0.075:
- 0.25 * 0.3 = 0.075
- 0.025 * 3 = 0.075
This is using the decimal number system commonly used.
Computers, at their core, however, don't use the decimal system, but binary – everything is based on 0 and 1.
Because of this, they actually have a hard time getting the calculation above right. JavaScript and other programming languages have to approximate the result, giving you this:
- 0.25 * 0.3 = 0.75
- 0.025 * 3 = 0.07500000000000001
You can now see why toFixed returns different results:
- 0.75.toFixed(2) = 0.07
- 0.07500000000000001.toFixed(2) = 0.08
(Math.round(num * 100) / 100).toFixed(2);
Live Demo
var num1 = "1";
document.getElementById('num1').innerHTML = (Math.round(num1 * 100) / 100).toFixed(2);
var num2 = "1.341";
document.getElementById('num2').innerHTML = (Math.round(num2 * 100) / 100).toFixed(2);
var num3 = "1.345";
document.getElementById('num3').innerHTML = (Math.round(num3 * 100) / 100).toFixed(2);
span {
border: 1px solid #000;
margin: 5px;
padding: 5px;
}
<span id="num1"></span>
<span id="num2"></span>
<span id="num3"></span>
Note that it will round to 2 decimal places, so the input 1.346 will return 1.35.
Number(1).toFixed(2); // 1.00
Number(1.341).toFixed(2); // 1.34
Number(1.345).toFixed(2); // 1.34 NOTE: See andy's comment below.
Number(1.3450001).toFixed(2); // 1.35
document.getElementById('line1').innerHTML = Number(1).toFixed(2);
document.getElementById('line2').innerHTML = Number(1.341).toFixed(2);
document.getElementById('line3').innerHTML = Number(1.345).toFixed(2);
document.getElementById('line4').innerHTML = Number(1.3450001).toFixed(2);
<span id="line1"></span>
<br/>
<span id="line2"></span>
<br/>
<span id="line3"></span>
<br/>
<span id="line4"></span>
It doesn't work insanely. You tell the function to keep two decimal digits and that's what it does. If you want to round your number, you can try multiplying your number with 10^x, using Math.round and then dividing by the same number:
const roundToDecimals = function (number, decimals) {
const num = Math.pow(10, decimals);
return Math.round(number * num) / num;
}
console.log(roundToDecimals(0.175, 2));
You have told to round it till 2 points .so the answer will be 0.17 because the third number is less than or equal to 5.
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.
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.