This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git

commit 5e54406ae9895dd9c9f5831e6fcd1a9fb2a7b52f
Author: aherbert <[email protected]>
AuthorDate: Tue Oct 3 15:04:59 2023 +0100

    Combine sums in double-double precision
    
    This enforces symmetry in the combine operation and maximises the
    precision from the available bits.
---
 .../java/org/apache/commons/numbers/core/Sum.java   | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git 
a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Sum.java 
b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Sum.java
index ee7b351f..eaee0d9b 100644
--- 
a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Sum.java
+++ 
b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Sum.java
@@ -196,16 +196,27 @@ public final class Sum
      * before addition to ensure there are no issues when adding a sum
      * to itself.
      *
+     * <p>This method sums the values in double-double precision.
+     * This enforces symmetry when combining sums and maximises the available 
precision.
+     *
      * @param s Sum.
      * @param c Compensation.
      * @return this instance.
      */
     private Sum add(double s, double c) {
-        add(s);
-        // compensation can be NaN from accumulating one or more same-signed 
infinite values.
-        // Do not pollute the regular IEEE754 sum with a spurious NaN.
-        if (!Double.isNaN(c)) {
-            add(c);
+        // Re-normalise the sums and combine in double-double precision.
+        // Note: The conversion to a DD is lossless.
+        final DD result = DD.ofSum(sum, comp).add(DD.ofSum(s, c));
+        if (result.isFinite()) {
+            sum = result.hi();
+            comp = result.lo();
+        } else {
+            // compensation can be NaN from accumulating one or more 
same-signed infinite values.
+            // Do not pollute the regular IEEE754 sum with a spurious NaN.
+            add(s);
+            if (!Double.isNaN(c)) {
+                add(c);
+            }
         }
         return this;
     }

Reply via email to