diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 4a7a8466c..5bdaf76c8 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -51,6 +51,9 @@ If the output is not quite correct, check for invisible trailing spaces!
+
+ Fixed FastMath.exp that potentially returned NaN for non-NaN argument.
+
Added a nth order Brent solver for general real fields, replacing the former
solver that was restricted to Dfp fields only.
diff --git a/src/main/java/org/apache/commons/math3/util/FastMath.java b/src/main/java/org/apache/commons/math3/util/FastMath.java
index 161ad6cf5..f30b50274 100644
--- a/src/main/java/org/apache/commons/math3/util/FastMath.java
+++ b/src/main/java/org/apache/commons/math3/util/FastMath.java
@@ -968,6 +968,13 @@ public class FastMath {
much larger than the others. If there are extra bits specified from the
pow() function, use them. */
final double tempC = tempB + tempA;
+
+ // If tempC is positive infinite, the evaluation below could result in NaN,
+ // because z could be negative at the same time.
+ if (tempC == Double.POSITIVE_INFINITY) {
+ return Double.POSITIVE_INFINITY;
+ }
+
final double result;
if (extra != 0.0) {
result = tempC*extra*z + tempC*extra + tempC*z + tempB + tempA;
diff --git a/src/test/java/org/apache/commons/math3/util/FastMathTest.java b/src/test/java/org/apache/commons/math3/util/FastMathTest.java
index aadc4ecd5..2df5542f5 100644
--- a/src/test/java/org/apache/commons/math3/util/FastMathTest.java
+++ b/src/test/java/org/apache/commons/math3/util/FastMathTest.java
@@ -215,6 +215,15 @@ public class FastMathTest {
}
Assert.assertEquals(0, maxErr, 3);
}
+
+ @Test
+ public void testMath1269() {
+ final double arg = 709.8125;
+ final double vM = Math.exp(arg);
+ final double vFM = FastMath.exp(arg);
+ Assert.assertTrue("exp(" + arg + ") is " + vFM + " instead of " + vM,
+ Precision.equalsIncludingNaN(vM, vFM));
+ }
@Test
public void testHyperbolicInverses() {