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>
|
<body>
|
||||||
<release version="3.1" date="TBD" description="
|
<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">
|
<action dev="tn" type="fix" issue="MATH-666">
|
||||||
Deprecated "FieldVector#getData()" in favor of "toArray()".
|
Deprecated "FieldVector#getData()" in favor of "toArray()".
|
||||||
</action>
|
</action>
|
||||||
|
|
|
@ -272,6 +272,28 @@ public class Precision {
|
||||||
return equals(x, y, 1) || FastMath.abs(y - x) <= eps;
|
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
|
* Returns true if both arguments are NaN or are equal or within the range
|
||||||
* of allowed error (inclusive).
|
* of allowed error (inclusive).
|
||||||
|
|
|
@ -27,6 +27,33 @@ import org.junit.Test;
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class PrecisionTest {
|
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
|
@Test
|
||||||
public void testEqualsIncludingNaN() {
|
public void testEqualsIncludingNaN() {
|
||||||
double[] testArray = {
|
double[] testArray = {
|
||||||
|
|
Loading…
Reference in New Issue