Pregunta

Possible Duplicate:
Moving decimal places over in a double

Why is the following sum of numbers not equal to 0.4622? but 0.46219999999999994

Double total = new Double(0.08) + new Double(0.0491) + new Double(0.3218) + 
         new Double(0.0113) + new Double(0.0); // = 0.46219999999999994

I have an application that checks the users input.

The user inputs 5 decimal numbers and a total number. The application checks if the sum of all 5 numbers capped at 4 decimals behind the komma is equal to the total number.

Capping it gives me 0.4621 which is not equal to 0.4622. I can't use DecimalFormat because it rounds it up. And if i explicitly say, round down then it will fail for this situation.

Any suggestion for how I can solve this?

¿Fue útil?

Solución

Try with java.math.BigDecimal. Double rounds result. You will just have to use add method, not + operator.

Otros consejos

Avoid using float and double if exact answers are required-- Item 48 -- Effective Java Second edition

Use BigDecimal instead.

Looks like a classic case of floating point arithmetic. If you want exact calculations, use java.math.BigDecimal. Have a look at What Every Computer Scientist Should Know About Floating-Point Arithmetic

When you use floating point arithmetic you must also use appropriate rounding.

BTW: Don't use an object when a primitive will do.

double total = 0.08 + 0.0491 + 0.3218 + 0.0113 + 0.0;
System.out.printf("%.4f%n", total);

double rounded = Math.round(total * 1e4) / 1e4;
if (rounded == 0.4622)
    System.out.println("rounded matched");

prints

0.4622
rounded matched

as expected.

Double and float in Java are internally represented as binary fractions and can therefore be not precise in representing decimal fractions (IEEE standard 754). If your decimal number calculations require precision, use Java.math.BigDecimal.

Floating point representation is a close approximation so you will have these little rounding errors when you use float and double. If you try to convert 0.08 to binary for instance you will realize that you cannot actually do it exactly. You need to consider this whenever you use double and float in calculations.

0.0810 = 0.00010100011110101110...2

a repeating pattern. So no matter how many bits you use this will have a rounding error.

That is yet another rounding issue. You should never compare doubles and expect them to be exactly equal. Instead define a small epsylon and expect the result to be within epsylon of the expected answer.

Any floating point value is inexact. The solution is to use DecimalFormat when you have to display the values. And no, it doesn't round up but to the nearest value.

From the javadoc :

DecimalFormat uses half-even rounding (see ROUND_HALF_EVEN) for formatting.

The internal representation of floating point numbers like Double is never a exact one. This is why during calculations such errors can occur.

It is always suggested to format such a result to a specific number of digits past the comma, so you result would be correctly be display as "0.4622" with 4 to 15 or more digits.

Perhaps checking the string input directly would be more feasible for you. That is check the length of characters after the decimal place.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top