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 6d3263198..c4e376da0 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 static int compareTo(double x, double y, double eps) { 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 623c95d33..5eac0e8c5 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 @@ void testCompare_NaN() { 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 8e784bf84..12a4f1f02 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; @@ -280,6 +282,30 @@ void testCompareToEpsilon() { Assertions.assertEquals(0, Precision.compareTo(Double.MIN_VALUE, -0.0, Double.MIN_VALUE)); } + @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;