Precision { public static boolean equalsIncludingNaN(float x, float y) { return (x != x || y != y) ? !(x != x ^ y != y) : equals(x, y, 1); } private  Precision(); static int compareTo(double x, double y, double eps); static int compareTo(final double x, final double y, final int maxUlps); static boolean equals(float x, float y); static boolean equalsIncludingNaN(float x, float y); static boolean equals(float x, float y, float eps); static boolean equalsIncludingNaN(float x, float y, float eps); static boolean equals(final float x, final float y, final int maxUlps); static boolean equalsIncludingNaN(float x, float y, int maxUlps); static boolean equals(double x, double y); static boolean equalsIncludingNaN(double x, double y); static boolean equals(double x, double y, double eps); static boolean equalsWithRelativeTolerance(double x, double y, double eps); static boolean equalsIncludingNaN(double x, double y, double eps); static boolean equals(final double x, final double y, final int maxUlps); static boolean equalsIncludingNaN(double x, double y, int maxUlps); static double round(double x, int scale); static double round(double x, int scale, int roundingMethod); static float round(float x, int scale); static float round(float x, int scale, int roundingMethod); static double representableDelta(double x,
                                            double originalDelta); static final double EPSILON; static final double SAFE_MIN; }
@Test public void testEqualsIncludingNaN() { double[] testArray = { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 1d, 0d }; for (int i = 0; i < testArray.length; i++) { for (int j = 0; j < testArray.length; j++) { if (i == j) { Assert.assertTrue(Precision.equalsIncludingNaN(testArray[i], testArray[j])); Assert.assertTrue(Precision.equalsIncludingNaN(testArray[j], testArray[i])); } else { Assert.assertTrue(!Precision.equalsIncludingNaN(testArray[i], testArray[j])); Assert.assertTrue(!Precision.equalsIncludingNaN(testArray[j], testArray[i])); } } } }
@Test public void testEqualsIncludingNaNWithAllowedDelta() { Assert.assertTrue(Precision.equalsIncludingNaN(153.0000, 153.0000, .0625)); Assert.assertTrue(Precision.equalsIncludingNaN(153.0000, 153.0625, .0625)); Assert.assertTrue(Precision.equalsIncludingNaN(152.9375, 153.0000, .0625)); Assert.assertTrue(Precision.equalsIncludingNaN(Double.NaN, Double.NaN, 1.0)); Assert.assertTrue(Precision.equalsIncludingNaN(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0)); Assert.assertTrue(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0)); Assert.assertFalse(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0)); Assert.assertFalse(Precision.equalsIncludingNaN(153.0000, 153.0625, .0624)); Assert.assertFalse(Precision.equalsIncludingNaN(152.9374, 153.0000, .0625)); }
@Test public void testEqualsIncludingNaNWithAllowedUlps() { Assert.assertTrue(Precision.equalsIncludingNaN(0.0, -0.0, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(1.0, 1 + FastMath.ulp(1d), 1)); Assert.assertFalse(Precision.equalsIncludingNaN(1.0, 1 + 2 * FastMath.ulp(1d), 1)); final double nUp1 = FastMath.nextAfter(1d, Double.POSITIVE_INFINITY); final double nnUp1 = FastMath.nextAfter(nUp1, Double.POSITIVE_INFINITY); Assert.assertTrue(Precision.equalsIncludingNaN(1.0, nUp1, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(nUp1, nnUp1, 1)); Assert.assertFalse(Precision.equalsIncludingNaN(1.0, nnUp1, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(0.0, FastMath.ulp(0d), 1)); Assert.assertTrue(Precision.equalsIncludingNaN(0.0, -FastMath.ulp(0d), 1)); Assert.assertTrue(Precision.equalsIncludingNaN(153.0, 153.0, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(153.0, 153.00000000000003, 1)); Assert.assertFalse(Precision.equalsIncludingNaN(153.0, 153.00000000000006, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(153.0, 152.99999999999997, 1)); Assert.assertFalse(Precision.equalsIncludingNaN(153, 152.99999999999994, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(-128.0, -127.99999999999999, 1)); Assert.assertFalse(Precision.equalsIncludingNaN(-128.0, -127.99999999999997, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(-128.0, -128.00000000000003, 1)); Assert.assertFalse(Precision.equalsIncludingNaN(-128.0, -128.00000000000006, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1)); Assert.assertTrue(Precision.equalsIncludingNaN(Double.NaN, Double.NaN, 1)); Assert.assertFalse(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000)); }