MATH-866
Method to test for equality with a given relative tolerance (due to Yannick Tanguy and Julien Anxionnat). Original patch provided in JIRA MATH-863 and committed with a few changes. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1387941 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b245e08d24
commit
600f00ba58
|
@ -52,6 +52,10 @@ If the output is not quite correct, check for invisible trailing spaces!
|
|||
<body>
|
||||
<release version="3.1" date="TBD" description="
|
||||
">
|
||||
<action dev="erans" type="add" issue="MATH-866" due-to="Yannick Tanguy">
|
||||
Added method to test for floating-point numbers equality with a
|
||||
relative tolerance (class "o.a.c.m.util.Precision").
|
||||
</action>
|
||||
<action dev="tn" type="fix" issue="MATH-666">
|
||||
Deprecated "FieldVector#getData()" in favor of "toArray()".
|
||||
</action>
|
||||
|
|
|
@ -272,6 +272,28 @@ public class Precision {
|
|||
return equals(x, y, 1) || FastMath.abs(y - x) <= eps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if there is no double value strictly between the
|
||||
* arguments or the reltaive difference between them is smaller or equal
|
||||
* to the given tolerance.
|
||||
*
|
||||
* @param x First value.
|
||||
* @param y Second value.
|
||||
* @param eps Amount of allowed relative error.
|
||||
* @return {@code true} if the values are two adjacent floating point
|
||||
* numbers or they are within range of each other.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if both arguments are NaN or are equal or within the range
|
||||
* of allowed error (inclusive).
|
||||
|
|
|
@ -27,6 +27,33 @@ import org.junit.Test;
|
|||
* @version $Id$
|
||||
*/
|
||||
public class PrecisionTest {
|
||||
@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));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsIncludingNaN() {
|
||||
double[] testArray = {
|
||||
|
|
Loading…
Reference in New Issue