I am trying to fix the number to 2 digits after decimal and for that i am using toFixed
function of javascript. Below are the strange results i am getting, please check and help me.
var number = 11.995; number.toFixed(2); // giving me 11.99 which is correct var number = 19.995; number.toFixed(2); // giving me 20.00 which is incorrect
Can anyone tell me why it is happening.
Thanks for your help.
I am trying to fix the number to 2 digits after decimal and for that i am using toFixed
function of javascript. Below are the strange results i am getting, please check and help me.
var number = 11.995; number.toFixed(2); // giving me 11.99 which is correct var number = 19.995; number.toFixed(2); // giving me 20.00 which is incorrect
Can anyone tell me why it is happening.
Thanks for your help.
Share Improve this question edited Aug 24, 2012 at 10:18 Felix Kling 817k181 gold badges1.1k silver badges1.2k bronze badges asked Aug 24, 2012 at 8:33 Ravinder SinghRavinder Singh 3,1336 gold badges33 silver badges46 bronze badges5 Answers
Reset to default 6This is how floating point math works. The value 19.995 is not exact binary (base 2). To make it more clear, think of an exact number when you divide 10/3.
For more in-depth explanations, read this: http://docs.oracle./cd/E19957-01/806-3568/ncg_goldberg.html
In your case you can work with strings instead (at least it seems like that is what you want):
number.toString().substr(0, n);
Or define a function like this (made in 2 minutes, just an example):
Number.toFixed = function(no, n) {
var spl = no.toString().split('.');
if ( spl.length > 1 ) {
return spl[0]+'.'+spl[1].substr(0,n);
}
return spl[0];
}
Number.toFixed(19.995, 2); // 19.99
toFixed
rounds the value. Since 19.995 is exactly halfway between 19.99 and 20.00, it has to choose one of them. Traditionally, rounding prefers the even result (this prevents bias, since round-ups and round-downs will be equal).
I have create a function which done all for me..
function toFixed(number, precision) {
var multiplier = Math.pow(10, precision + 1),
wholeNumber = Math.floor(number * multiplier);
return Math.round(wholeNumber / 10) * 10 / multiplier;
}
//Call this function to retrive exect value
toFixed((+adjustmentval), 2);
David has answered your doubt I'm guessing. Just providing an alternate solution here.
You can use the Math.floor()
method of the Math object for this.
Something like this, Math.floor(number*100)/100
Can anyone tell me why it is happening.
The IEEE-754 double-precision binary floating point number standard used by JavaScript's number
type (and similar times in several other languages) does not perfectly store all numbers, it stores some numbers imprecisely, in a way that lets it A) Store them in just 64 bits, and B) Calculate with them quickly.
For 11.995
, the actual value is 11.99499988555908203125
, just slightly less than 11.995
.
For 19.995
, the actual value is 19.9950008392333984375
, just slightly more than 19.995
.
That explains why when you round them using the usual round-to-nearest-half-up operation, 11.995
(which is really 11.99499988555908203125
) rounds down to 11.99
but 19.995
(which is really 19.9950008392333984375
) rounds up to 20.00
.
(This site has a handy calculator for visualizing this stuff.)
More here on SO:
- Is floating point math broken?
- How to deal with floating point number precision in JavaScript?