Finding Floating-Point Sum
If the problem is to find two array elements x and y such that their sum is the target number z when added with floating-point arithmetic, then the floating-point rounding issues are largely irrelevant.
An algorithm for the Two Sum problem is:
- Sort the elements. (To remember their original indices in the array, associate the elements with their indices and retain those associations while sorting.)
- Set
L
to point to the lowest element and H
to point to the highest element.
- While L is earlier than H:
- If the sum of
*L
(the number pointed to by L
) and *H
is z, stop. The desired elements are *L
and *H
.
- If the sum is less than z, advance
L
.
- If the sum is greater than z, decrease
H
.
- Stop. There is no solution.
Floating-point rounding is not a problem because floating-point addition is (weakly) monotonic: If the floating-point sum of x0 < x1, then the floating-point sum of x0 and y is less than or equal to the floating-point sum of x=1 and y. This means the test sum of *L
and *H
in the algorithm always correctly indicates whether L
or H
must be adjusted to continue the search—if the test sum is too low, then we need a higher number, so L
must be advanced. Similarly, if the test sum is too high, H
must be decreased. No solution can be missed this way.
Finding Real-Number Sum
If the problem is to find two array elements x and y such that there sum is the target number z when added with real-number arithmetic, then the above algorithm suffices with a simple modification to the test.
Replace step 3. above with:
- Evaluate
s = *L + *H; z = s - *L; t = *H - z;
with floating-point arithmetic using round-to-nearest. Then, in real-number arithmetic, s
+ t
is exactly *L
+ *H
.1 s
contains the most significant portion of the sum (the nearest value representable in floating-point), and t
contains the error or deviation of s
from the real-number sum of *L
and *H
. If s
equals z and t
equals zero, stop. The desired elements are *L
and *H
.
- If
s
< z or s
= z and t
< 0, advance L
.
- Otherwise, decrease
H
.
Footnote
1 Muller et al, Handbook of Floating-Point Arithmetic, 2010, Theorem 4, pages 126-129.