Skip to content

Commit

Permalink
NUMBERS-154: Handle NaN to allow consistent sorting.
Browse files Browse the repository at this point in the history
Thanks to Alex Herbert.
  • Loading branch information
Gilles Sadowski committed Apr 23, 2021
1 parent dbd2a47 commit 4f0cf07
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
Expand Up @@ -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);
}

/**
Expand Down
Expand Up @@ -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));
}

Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 4f0cf07

Please sign in to comment.