0

This is my form:

<input type="text" class="form-control amount" value="" placeholder="amount" />
<input type="hidden" class="price" value="3.30" />
<input type="text" class="form-control total" value="" disabled />

My js:

$('.amount').on('keyup', function (e) {
    e.preventDefault();
    
    var amount = $('.amount').val(); 
    var total = Number(amount) * Number($('.price').val());
  
    $('.total').val(total);
});

If i fill in an amount of 3, the result in input with class total shows me: 9.899999999999999 instead of 19.80. (3 * 3.30 is exactly 9.90).

Can someone explain me why the result is so many chars behind the dot?

I know i can reduce the result in 2 decimals with .toFixed(2) but that doesn't explain for me why a value which is exactly 9.90 changes into 9.899999999999999

Fiddle

john
  • 1,263
  • 5
  • 18
  • 1
    Does this answer your question? [How to deal with floating point number precision in JavaScript?](https://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript) – GalAbra Sep 11 '21 at 15:55
  • 1
    Also this I think is related: https://stackoverflow.com/questions/588004/is-floating-point-math-broken – vanowm Sep 11 '21 at 15:56

2 Answers2

1

This is because the way float numbers are stored as binary digits. To enable a wide rage of numbers and still maintain a reasonable size in memory for each number, the precision of results is sacrificed a bit. You can read more about here https://stackoverflow.com/a/588014/3807365

IT goldman
  • 14,885
  • 2
  • 14
  • 28
1

This happens due to the how floating point arithmetic works. In a few words, the floating number is not represented internally as-is, so when the language goes back and forth to display it, there can be some precision issues (such as the one you are facing). See the link for more details.

In summary, as you seem to be handling currency calculations, your best option is to use, instead of float, a specific datatype such as currency.js:

$('.amount').on('keyup', function (e) {
    e.preventDefault();
    
    var amount = $('.amount').val(); 
    var total = currency(amount).multiply(currency($('.price').val()));
  
    $('.total').val(total);
});
<script src="https://cdn.jsdelivr.net/npm/currency.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" class="form-control amount" value="" placeholder="amount" />
<input type="hidden" class="price" value="3.30" />
<input type="text" class="form-control total" value="" disabled />

There are many libs for that, another one is dinero.js.

acdcjunior
  • 132,397
  • 37
  • 331
  • 304