4

I am trying to fix the number to 2 digits after decimal and for that i am using toFixedfunction 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.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Ravinder Singh
  • 3,113
  • 6
  • 30
  • 46

5 Answers5

6

This 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.com/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
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • @RobW correct, but it was not meant to be an exact replacement just in theory. But thanks! – David Hellsing Aug 24 '12 at 09:10
  • 0,4 only gives 1 decimal in this case. You'd better use `indexOf` to detect the dot, or just use a RegExp for a one-liner: `/-?\d+(\.\d{0,2})?/`. Note: The regexp is not complete, it doesn't deal with exponents. – Rob W Aug 24 '12 at 09:14
1

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).

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • It doesn’t "choose". 19.995 is not *exactly* halfway, since floating numbers are not exact in javascript. You can test this by adding `19.999991 + 0.000004` wich equals `19.999995000000002`. – David Hellsing Aug 24 '12 at 11:19
  • 1
    Some floating point fractions are exact, though, such as 0.5. However, it looks like I was wrong about it rounding to even, it always rounds up. `0.5.toFixed(0)` is 1, `1.5.toFixed(0)` is 2. – Barmar Aug 24 '12 at 11:28
  • 2
    No it doesn’t always round up, and that was the original question. F.ex `(11.995).toFixed(2)` is 11.99 – David Hellsing Aug 24 '12 at 11:30
  • 1
    That's because of what you said earlier, that it isn't exact. The one that are exactly halfway round up. – Barmar Aug 24 '12 at 11:33
1

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);
Kaushal Khamar
  • 2,097
  • 1
  • 17
  • 23
  • My thoughts exactly! Too bad `toFixed` doesn't do that - how are we supposed to know there might be a problem? Well, I guess that we should be aware(?)... – iAmOren Jul 03 '20 at 03:56
0

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

painotpi
  • 6,894
  • 1
  • 37
  • 70
0

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:

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875