This is an automated email from the ASF dual-hosted git repository. erans pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
The following commit(s) were added to refs/heads/master by this push: new 4f0cf07 NUMBERS-154: Handle NaN to allow consistent sorting. 4f0cf07 is described below commit 4f0cf073de18650a2cedd9c1ca07cff9bee44d8d Author: Gilles Sadowski <gillese...@gmail.com> AuthorDate: Fri Apr 23 02:26:49 2021 +0200 NUMBERS-154: Handle NaN to allow consistent sorting. Thanks to Alex Herbert. --- .../org/apache/commons/numbers/core/Precision.java | 5 ++++- .../numbers/core/EpsilonDoubleEquivalenceTest.java | 8 +++---- .../apache/commons/numbers/core/PrecisionTest.java | 26 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Precision.java b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Precision.java index 6d32631..c4e376d 100644 --- a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Precision.java +++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Precision.java @@ -112,8 +112,11 @@ public final class Precision { return 0; } else if (x < y) { return -1; + } else if (x > y) { + return 1; } - return 1; + // NaN input. + return Double.compare(x, y); } /** diff --git a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/EpsilonDoubleEquivalenceTest.java b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/EpsilonDoubleEquivalenceTest.java index 623c95d..5eac0e8 100644 --- a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/EpsilonDoubleEquivalenceTest.java +++ b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/EpsilonDoubleEquivalenceTest.java @@ -121,14 +121,14 @@ class EpsilonDoubleEquivalenceTest { final Precision.DoubleEquivalence cmp = Precision.doubleEquivalenceOfEpsilon(1e-6); // act/assert - Assertions.assertEquals(1, cmp.compare(0, Double.NaN)); + Assertions.assertEquals(-1, cmp.compare(0, Double.NaN)); Assertions.assertEquals(1, cmp.compare(Double.NaN, 0)); - Assertions.assertEquals(1, cmp.compare(Double.NaN, Double.NaN)); + Assertions.assertEquals(0, cmp.compare(Double.NaN, Double.NaN)); - Assertions.assertEquals(1, cmp.compare(Double.POSITIVE_INFINITY, Double.NaN)); + Assertions.assertEquals(-1, cmp.compare(Double.POSITIVE_INFINITY, Double.NaN)); Assertions.assertEquals(1, cmp.compare(Double.NaN, Double.POSITIVE_INFINITY)); - Assertions.assertEquals(1, cmp.compare(Double.NEGATIVE_INFINITY, Double.NaN)); + Assertions.assertEquals(-1, cmp.compare(Double.NEGATIVE_INFINITY, Double.NaN)); Assertions.assertEquals(1, cmp.compare(Double.NaN, Double.NEGATIVE_INFINITY)); } diff --git a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/PrecisionTest.java b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/PrecisionTest.java index 8e784bf..12a4f1f 100644 --- a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/PrecisionTest.java +++ b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/PrecisionTest.java @@ -16,6 +16,8 @@ */ package org.apache.commons.numbers.core; +import java.util.Arrays; +import java.util.Collections; import java.math.RoundingMode; import org.junit.jupiter.api.Assertions; @@ -281,6 +283,30 @@ class PrecisionTest { } @Test + void testSortWithCompareTo() { + final Double[] array = {Double.NaN, 0.02, 0.01, Double.NaN, 2.0, 1.0}; + final double eps = 0.1; + for (int i = 0; i < 10; i++) { + Collections.shuffle(Arrays.asList(array)); + Arrays.sort(array, (a, b) -> Precision.compareTo(a, b, eps)); + + for (int j = 0; j < array.length - 1; j++) { + final int c = Precision.compareTo(array[j], + array[j + 1], + eps); + // Check that order is consistent with the comparison function. + Assertions.assertNotEquals(c, 1); + } + Assertions.assertTrue(array[0] == 0.01 || array[0] == 0.02); + Assertions.assertTrue(array[1] == 0.01 || array[1] == 0.02); + Assertions.assertEquals(1, array[2], 0d); + Assertions.assertEquals(2, array[3], 0d); + Assertions.assertTrue(Double.isNaN(array[4])); + Assertions.assertTrue(Double.isNaN(array[5])); + } + } + + @Test void testCompareToMaxUlps() { double a = 152.32; double delta = Math.ulp(a);