I was just reading about rounding errors in C++. So, if I'm making a math intense program (or any important calculations) should I just drop floats all together and use only doubles or is there an easier way to prevent rounding errors?
-
2What math intense program is this? Being math intense doesn't mean you need to prevent this kind of floating-point errors.R. Martinho Fernandes– R. Martinho Fernandes2011-07-20 09:44:42 +00:00Commented Jul 20, 2011 at 9:44
-
5Using doubles doesn't prevent rounding errors.Mat– Mat2011-07-20 09:47:03 +00:00Commented Jul 20, 2011 at 9:47
-
@Martinho, I do when customers expect something at least almost accurate >_>Freesnöw– Freesnöw2011-07-20 09:49:19 +00:00Commented Jul 20, 2011 at 9:49
-
@Mat: Moreover, almost any reasonable modern architecture will promote your floats to doubles anyway, so why bother with the floats at all. (Old CUDA notwithstanding, that is.) OP: If you need guaranteed precision, use a multiprecision library like MPFR.Kerrek SB– Kerrek SB2011-07-20 09:49:58 +00:00Commented Jul 20, 2011 at 9:49
-
7You need well-defined accuracy requirements and a good understanding of the algorithm that you are implementing and how sensitive it is to rounding errors (aka numerical stability).Paul R– Paul R2011-07-20 09:50:21 +00:00Commented Jul 20, 2011 at 9:50
3 Answers
Obligatory lecture: What Every Programmer Should Know About Floating-Point Arithmetic.
Also, try reading IEEE Floating Point standard.
You'll always get rounding errors. Unless you use an infinite arbitrary precision library, like gmplib. You have to decide if your application really needs this kind of effort.
Or, you could use integer arithmetic, converting to floats only when needed. This is still hard to do, you have to decide if it's worth it.
Lastly, you can use float or double taking care not to make assumption about values at the limit of representation's precision. I'd wish this Valgrind plugin was implemented (grep for float)...
1 Comment
The rounding errors are normally very insignificant, even using floats. Mathematically-intense programs like games, which do very large numbers of floating-point computations, often still use single-precision.
2 Comments
This might work if your highest number is less than 10 billion and you're using C++ double precision.
if ( ceil(10000*(x + 0.00001)) > ceil(100000*(x - 0.00001))) {
x = ceil(10000*(x + 0.00004)) / 10000;
}
This should allow at least the last digit to be off +/- 9. I'm assuming dividing by 1000 will always just move a decimal place. If not, then maybe it could be done in binary.
You would have to apply it after every operation that is not +, -, *, or a comparison. For example, you can't do two divisions in the same formula because you'd have to apply it to each division.
If that doesn't work, you could work in integers by scaling the numbers up and always use integer division. If you need advanced functions maybe there is a package that does deterministic integer math. Integer division is required in a lot of financial settings because of round off error being subject to exploit like in the movie "The Office".