MATH-708.
New utility method. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1203205 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e0bf2f8c29
commit
9591a91f45
|
@ -473,4 +473,24 @@ public class Precision {
|
|||
}
|
||||
return unscaled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes a number {@code delta} close to {@code originalDelta} with
|
||||
* the property that <pre><code>
|
||||
* x + delta - x
|
||||
* </code></pre>
|
||||
* is exactly machine-representable.
|
||||
* This is useful when computing numerical derivatives, in order to reduce
|
||||
* roundoff errors.
|
||||
*
|
||||
* @param x Value.
|
||||
* @param originalDelta Offset value.
|
||||
* @return a number {@code delta} so that {@code x + delta} and {@code x}
|
||||
* differ by a representable floating number.
|
||||
*/
|
||||
public static double representableDelta(double x,
|
||||
double originalDelta) {
|
||||
return x + originalDelta - x;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -464,4 +464,22 @@ public class PrecisionTest {
|
|||
Assert.assertEquals(Float.POSITIVE_INFINITY, Precision.round(Float.POSITIVE_INFINITY, 2), 0.0f);
|
||||
Assert.assertEquals(Float.NEGATIVE_INFINITY, Precision.round(Float.NEGATIVE_INFINITY, 2), 0.0f);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRepresentableDelta() {
|
||||
int totalCount = 0;
|
||||
int nonRepresentableCount = 0;
|
||||
final double x = 100;
|
||||
final int numTrials = 10000;
|
||||
for (int i = 0; i < numTrials; i++) {
|
||||
final double originalDelta = Math.random();
|
||||
final double delta = Precision.representableDelta(x, originalDelta);
|
||||
if (delta != originalDelta) {
|
||||
++nonRepresentableCount;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue(nonRepresentableCount / (double) numTrials > 0.9);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue