0

toFixed() function responding differently for float values. For Example:

 var a = 2.555;
 var b = 5.555;

console.log(a.toFixed(2));  /* output is 2.56 */ 
console.log(b.toFixed(2));  /* output is 5.55 */

For 2.555/3.555 results are (2.56/3.56)

and

For other values(not sure for all values) it is showing #.55 (# refers to any number)

I am confused can any one help me out.

Thanks in advance.

Musa
  • 96,336
  • 17
  • 118
  • 137
PHP Worm...
  • 4,109
  • 1
  • 25
  • 48
  • possible duplicate of [toFixed javascript function giving strange results?](http://stackoverflow.com/questions/12105787/tofixed-javascript-function-giving-strange-results) – Naeem Shaikh Mar 12 '15 at 11:09
  • This is not a duplicate one, in the link above the answer that is approved is an alternative of toFixed() function I don't want alternative I want t know the exact reason why toFixed() function is working like this. @NoDownvotesPlz – PHP Worm... Mar 12 '15 at 11:25
  • 2
    Please check this url: http://stackoverflow.com/questions/10768083/tofixed2-rounds-x-525-inconsistently. It helps you hopefully. – Alive to die - Anant Mar 12 '15 at 11:57

3 Answers3

8

Javascript uses a binary floating point representation for numbers (IEEE754). This format is able to represent exactly (without approximation) only numbers that can be expressed in the form n/2m where both n and m are integers.

Any number that is not a rational where the denominator is an integral power of two cannot be represented exactly because in binary it is a periodic number (it has infinite binary digits after the point).

The number 0.5 (i.e. 1/2) is fine, (in binary is just 0.1₂) but for example 0.55 (i.e. 11/20) cannot be represented exactly (in binary it's 0.100011001100110011₂… i.e. 0.10(0011)₂ with the last part 0011₂ repeating infinite times).

If you need to do any computation in which the result depends on exact decimal numbers you need to use an exact decimal representation. A simple solution if the number of decimals is fixed (e.g. 3) is to keep all values as integers by multiplying them by 1000...

2.555 --> 2555
5.555 --> 5555
3.7   --> 3700

and adjusting your computation when doing multiplications and divisions accordingly (e.g. after multiplying two numbers you need to divide the result by 1000).

The IEEE754 double-precision format is accurate with integers up to 9,007,199,254,740,992 and this is often enough for prices/values (where the rounding is most often an issue).

6502
  • 112,025
  • 15
  • 165
  • 265
3

Try this Demo Here

function roundToTwo(num) {    
    alert(+(Math.round(num + "e+2")  + "e-2"));
}

roundToTwo(2.555);
roundToTwo(5.555);
I'm Geeker
  • 4,601
  • 5
  • 22
  • 41
0

toFixed() method depending on Browser rounds down or retain.

Here is the solution for this problem, check for "5" at the end

 var num = 5.555;
 var temp = num.toString();
if(temp .charAt(temp .length-1)==="5"){
temp = temp .slice(0,temp .length-1) + '6';
}
num = Number(temp);
Final = num.toFixed(2);

Or reusable function would be like

function toFixedCustom(num,upto){

     var temp = num.toString();
    if(temp .charAt(temp .length-1)==="5"){
    temp = temp .slice(0,temp .length-1) + '6';
    }
    num = Number(temp);
    Final = num.toFixed(upto);
    return Final;
}

var a = 2.555;
 var b = 5.555;

console.log(toFixedCustom(a,2));  
console.log(toFixedCustom(b,2));  
A.B
  • 20,110
  • 3
  • 37
  • 71