Java - maximum loss of accuracy in one double addition / subtraction

Is it even possible to roughly set the maximum loss of accuracy when working with two double values ​​in java (add / subtract)? Probably the worst case scenario is that two numbers cannot be represented exactly, and then an operation is performed on them, which leads to a value that is also impossible to represent accurately.

+7
source share
3 answers

Take a look at Math.ulp(double) . Ulp a double is the delta to the next highest value. For example, if you add one to the numbers and one is less than the ulp of the other, you know that adding will have no effect. If you multiply two doubles, you can multiply them with ulps to get the maximum result error.

+5
source

In the worst case, all accuracy may be lost. This can happen, for example, if the result is greater than the largest representable finite number. It will then be saved as POSITIVE_INFINITY (or NEGATIVE_INFINITY).

As for your update, this may happen with the addition.

 double a = Double.MAX_VALUE; System.out.println(a); double b = a + a; System.out.println(b); 

Result:

 1.7976931348623157E308 Infinity 

Watch online: ideone

In general, the size of the presentation error depends on the size of your numbers.

+7
source

You can see the actual accuracy of your inputs, for example, the code below the outputs:

 input: 0.01000000000000000020816681711721685132943093776702880859375 range: [0.0099999999999999984734433411404097569175064563751220703125 - 0.010000000000000001942890293094023945741355419158935546875] range size: 3.4694469519536141888238489627838134765625E-18 input: 10000000000000000 range: [9999999999999998 - 10000000000000002] range size: 4 
 public static void main(String[] args) { printRange(0.01); printRange(10000000000000000d); } private static void printRange(double d) { long dBits = Double.doubleToLongBits(d); double dNext = Double.longBitsToDouble(dBits + 1); double dPrevious = Double.longBitsToDouble(dBits + -1); System.out.println("input: " + new BigDecimal(d)); System.out.println("range: [" + new BigDecimal(dPrevious) + " - " + new BigDecimal(dNext) + "]"); System.out.println("range size: " + new BigDecimal(dNext - dPrevious)); } 

You still need to evaluate the loss of the result of your operation. And this does not work with corner cases (around Infinity, NaN, etc.).

0
source

All Articles