Precision { public static boolean equalsWithRelativeTolerance(double x, double y, double eps) { if (equals(x, y, 1)) { return true; } final double absoluteMax = FastMath.max(FastMath.abs(x), FastMath.abs(y)); final double relativeDifference = FastMath.abs((x - y) / absoluteMax); return relativeDifference <= eps; } 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 testEqualsWithRelativeTolerance() { Assert.assertTrue(Precision.equalsWithRelativeTolerance(0d, 0d, 0d)); Assert.assertTrue(Precision.equalsWithRelativeTolerance(0d, 1 / Double.NEGATIVE_INFINITY, 0d)); final double eps = 1e-14; Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654988, eps)); Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654987, eps)); Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654948, eps)); Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654949, eps)); Assert.assertFalse(Precision.equalsWithRelativeTolerance(Precision.SAFE_MIN, 0.0, eps)); Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.0000000000001e-300, 1e-300, eps)); Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.00000000000001e-300, 1e-300, eps)); Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, 1.23, eps)); Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.POSITIVE_INFINITY, 1.23, eps)); Assert.assertTrue(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, eps)); Assert.assertTrue(Precision.equalsWithRelativeTolerance(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, eps)); Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, eps)); Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NaN, 1.23, eps)); Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NaN, Double.NaN, eps)); }