2

I started having problems with decimals which made me learn about the whole floating point math. My question is, what's a viable solution for it?

x = 0.1;
y = 0.2;
num = x + y;
num = Math.round(num * 100) / 100;

or

x = 0.1;
y = 0.2;
num = x + y;
num = num.toFixed(2); 
num = Number(num);

Are these both 100% viable options? As in, never have to worry about having the same problem anymore? Which one would you recommend? Or would you recommend a different solution? Any reason to use one solution over the other? Thanks in advance for any help.

EDIT: Sorry I wasn't more specific. I'm fine with it always being 2 decimals, since that won't be a problem for my project. Obviously if you want more decimals you would use 1000 instead of 100 and toFixed(3), and so on. My main concern is, are the above 2 solutions 100% viable, as in, I won't have to worry about any of the same problems? And also, would you recommend the first solution or the second? Or another one altogether? Since I will be using a method quite a lot for many calculations. Thanks again for your help.

Hate Names
  • 1,596
  • 1
  • 13
  • 20
  • 5
    Depends on what problem you are trying to solve – Chad Aug 02 '13 at 22:22
  • What _was_ your original problem? – federico-t Aug 02 '13 at 22:23
  • 1
    possible duplicate: [Is JavaScript's Floating-Point Math Broken?](http://stackoverflow.com/questions/588004/is-javascripts-floating-point-math-broken) – Cole Tobin Aug 02 '13 at 22:23
  • @Cole"Cole9"Johnson, this is a code style question, not a confusion about floating point math internals. – Brigand Aug 02 '13 at 22:24
  • In this specific case for those values, yes, both of them are viable. But if you have `x = 0.001` and `y = 0.002` neither of them work. – JJJ Aug 02 '13 at 22:24
  • From the answer to the question @Cole linked to: `equal = (Math.abs(x - y) < 0.000001)` – Xynariz Aug 02 '13 at 22:26
  • Sorry I wasn't more specific. I'm fine with it always being 2 decimals, since that won't be a problem for my project. My main concern is, are the above 2 solutions 100% viable, as in I won't have to worry about any of the same problems? And also, would you recommend the first solution or the second? Or another one altogether? Since I will have be using that method quite a lot for many calculations. Thanks again for your help. – Hate Names Aug 02 '13 at 22:30
  • 4
    If you're dealing with currency (cannot have >2 decimals), you can always change how you store/manipulate your data - have 1 mean one cent and 100 mean one dollar. – Xynariz Aug 02 '13 at 22:32
  • Nah, I'm not using a form of currency. I actually need decimals, but not 10+ decimals that I get from the strange math, along with the inaccurate addition and subtraction I might get when it equals really close to 0. Also the cole answer is no good for my solution, thanks for trying to help. I really appreciate it – Hate Names Aug 02 '13 at 22:41
  • 1
    Currency was only mentioned becsuse it's a natural way of working with integers (cents) rather than decimals (dollars). You can use any multiplier of 10 to get the right number of decimals. Floating point results still would pop up in multiplication and division, though, so you'd still need some rounding for that. – Jongware Aug 03 '13 at 00:31

1 Answers1

2

This is not a problem with JavaScript's floating point implementation, or something that will go away if you use a string formatting function like toFixed (the MDN docs for it here make clear that it is a string representation returned, not some other format of number). Rather, this is an inherent property of floating point arithmetic as a concept - it has a variable accuracy designed to closely approximate values within a certain range.

If you want your values to always be entirely accurate, the only solution is not to use floating point numbers. Generally, this is done by using integers representing some fraction of the "whole" numbers you're dealing with (e.g. pence/cents instead of pounds/euros/dollars, or milliseconds instead of seconds). Alternatively, you may be able to find a precision maths library which performs fixed-point arithmetic, so avoids the inaccuracies but will have worse performance.

If you don't mind the risk of the inaccuracies slowly building up, you can simply use formatting functions to only display to a certain precision when you output the result of a calculation. There is little point in converting to a string with a fixed precision and then back to a number, as the floating point implementation may still be unable to represent that number with complete precision.

IMSoP
  • 89,526
  • 13
  • 117
  • 169