0

I'm writing a simple invoicing solution for our company and have to multiply quantity * rate and round the result to two decimal places.

Quantity: 36.5
Rate: 33.33

My multiplication looks like this:

console.log((36.5 * 33.33).toFixed(2))

which returns

1216.54

when it should actually be

1216.55

I think this is because JavaScript is rounding down instead of up. Any idea how to resolve this?

Thanks!

Frank
  • 614
  • 1
  • 8
  • 31

1 Answers1

0

Function work as it described in ES standart. It doesn't round down (not always).

I skip first 7 steps of algorithm in standard (they are not significant in this case).

variables definition:

f - is number of digits required after dot
x - is number (in our case 1216.5449999)

In brackets I describe what happens and why so.

  1. x is lower then 10^21 so

    a) let n be integer for which the exact mathematical value of n ÷ 10^f – x is as close to zero as possible. (n will be 121654)

    (difference will be -0.4999999, with rights rounding (121655) difference will be (0.50000000)).

    b) let m be the String consisting of the digits of the decimal representation of n (m is "121654")

    c) f != 0 is true so

        i) Let k be the number of characters in m.(k = 6)
        ii) if k < f (not out case skipping it)
        iii) Let a be the first k–f characters of m (a = "1216"), and let b be the remaining f characters of m (m = "54")
        iv) Let m = a + "." + b. (m = "1216.54")
    
  2. return m;

If you still worry about right rounding in your app. then you, probably, should write your own rounding method (also you may try to search npm library for it. I don't know are they exist).

Edit:

Function with right rounding (it's slow but do the trick):

function myToFixed( val, digits_num ){
   if( ! digits_num ) digits_num = 0

   var tmp = val.toString().split('.')
   var decimal = tmp[1]
   var full = tmp[0];
   var regex = /[5-9]/
   var match = regex.exec( decimal.slice( digits_num ) )
   if( ! match ){ return val.toFixed( digits_num ) }
   var i = match.index + digits_num
   while( i >= digits_num ){ val = ( parseFloat( val ).toFixed( i ) );  i-- }

  return val.toString()
}
Arnial
  • 1,433
  • 1
  • 11
  • 10