Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java double losing precision calculation

I have the following double calculation in Java:

double C1 = some value;    // It's always an integer
double C2 = some value;    // It's always integer, and C2 >= C1
double S = some value;     // It's always 0 < S <= 1
double carry = some value; // It's always 0 <= carry < 1

double rate = ((C1/C2)/S);
double C3 = Math.floor( (rate * S * C2) + carry );

Now, if we did not lose precision, C3 == C1 would be true. But since we lose precision, will C3 and C1 still always be equal?

If they would not always be equal, if I have C1, C2, S, and C3, how could I modify the rate to make sure after calculation C3 would be equal to C1?

Note: unfortunately using BigDecimal is not an option.

like image 376
user1819676 Avatar asked Apr 15 '16 06:04

user1819676


People also ask

How much precision does a double have in Java?

A double is a 64 bit IEEE 754 floating-point. Double can provide precision up to 15 to 16 decimal points.

How do you stop a double from rounding in Java?

We can use DecimalFormat("0.00") to ensure the number always round to 2 decimal places.

Why is double not accurate?

doubles are not exact. It is because there are infinite possible real numbers and only finite number of bits to represent these numbers.


2 Answers

Generally, we don't compare two double values directly through ==. Instead, we measure the difference between them. e.g. Math.abs(C3 - C1) < 1e-6.

like image 148
Hongliang Avatar answered Sep 21 '22 04:09

Hongliang


Not so.

Floating point is an approximation. The next double, bit 1 added to the mantissa can cause a quite large gap for large exponents between those two doubles.

S approximating 0 will cause huge doubles, that have a large gap between them. That will no longer be correctable, say with that simple rounding. Even if the small S does not cause the division to exceed the double range with INFINITY.

One can easily be of by 1000.

like image 39
Joop Eggen Avatar answered Sep 18 '22 04:09

Joop Eggen