Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding and subtracting doubles are giving strange results [duplicate]

Tags:

java

double

So when I add or subtract in Java with Doubles, it giving me strange results. Here are some:

If I add 0.0 + 5.1, it gives me 5.1. That's correct.

If I add 5.1 + 0.1, it gives me 5.199999999999 (The number of repeating 9s may be off). That's wrong.

If I subtract 4.8 - 0.4, it gives me 4.39999999999995 (Again, the repeating 9s may be off). That's wrong.

At first I thought this was only the problem with adding doubles with decimal values, but I was wrong. The following worked fine:

5.1 + 0.2 = 5.3 5.1 - 0.3 = 4.8 

Now, the first number added is a double saved as a variable, though the second variable grabs the text from a JTextField. For example:

//doubleNum = 5.1 RIGHT HERE //The textfield has only a "0.1" in it. doubleNum += Double.parseDouble(textField.getText()); //doubleNum = 5.199999999999999 
like image 236
Rob Avery IV Avatar asked Mar 25 '13 21:03

Rob Avery IV


People also ask

What are doubles in subtraction?

Today we learned about “Doubles in Subtraction”. In addition, “doubles” equations (one number added to the same number) are easy to recall because they are “novel”... they stand out. These doubles equations can also be helpful in subtraction.

What is the use-doubles strategy for addition?

The use-doubles strategy for addition is one of many important strategies included in The Box and Book of Facts for Addition and Subtraction from ORIGO Education. Use these strategies to grow the doubles fact fluency and mental computation power of YOUR students!

What is a double value in Java?

In Java, double values are IEEE floating point numbers. Unless they are a power of 2 (or sums of powers of 2, e.g. 1/8 + 1/4 = 3/8), they cannot be represented exactly, even if they have high precision. Some floating point operations will compound the round-off error present in these floating point numbers.

What is the best way to represent a double value?

Appropriate names would be "coarse approximations" and "slightly better, but still coarse approximations" In Java, double values are IEEE floating point numbers. Unless they are a power of 2 (or sums of powers of 2, e.g. 1/8 + 1/4 = 3/8), they cannot be represented exactly, even if they have high precision.


2 Answers

In Java, double values are IEEE floating point numbers. Unless they are a power of 2 (or sums of powers of 2, e.g. 1/8 + 1/4 = 3/8), they cannot be represented exactly, even if they have high precision. Some floating point operations will compound the round-off error present in these floating point numbers. In cases you've described above, the floating-point errors have become significant enough to show up in the output.

It doesn't matter what the source of the number is, whether it's parsing a string from a JTextField or specifying a double literal -- the problem is inherit in floating-point representation.

Workarounds:

  • If you know you'll only have so many decimal points, then use integer arithmetic, then convert to a decimal:

    (double) (51 + 1) / 10 (double) (48 - 4) / 10 
  • Use BigDecimal

  • If you must use double, you can cut down on floating-point errors with the Kahan Summation Algorithm.

like image 131
rgettman Avatar answered Sep 19 '22 08:09

rgettman


In Java, doubles use IEEE 754 floating point arithmetic (see this Wikipedia article), which is inherently inaccurate. Use BigDecimal for perfect decimal precision. To round in printing, accepting merely "pretty good" accuracy, use printf("%.3f", x).

like image 20
raptortech97 Avatar answered Sep 21 '22 08:09

raptortech97