diff --git a/src/main/java/org/apache/commons/math/util/FastMath.java b/src/main/java/org/apache/commons/math/util/FastMath.java
index 5f012fb95..b9ebdc0a9 100644
--- a/src/main/java/org/apache/commons/math/util/FastMath.java
+++ b/src/main/java/org/apache/commons/math/util/FastMath.java
@@ -599,6 +599,14 @@ public class FastMath {
return nextAfter(a, Double.POSITIVE_INFINITY);
}
+ /** Compute next number towards positive infinity.
+ * @param a number to which neighbor should be computed
+ * @return neighbor of a towards positive infinity
+ */
+ public static float nextUp(final float a) {
+ return nextAfter(a, Float.POSITIVE_INFINITY);
+ }
+
/** Returns a pseudo-random number between 0.0 and 1.0.
* @return a random number between 0.0 and 1.0
*/
@@ -3356,8 +3364,16 @@ public class FastMath {
public static double nextAfter(double d, double direction) {
// handling of some important special cases
- if (Double.isNaN(d) || Double.isInfinite(d)) {
+ if (Double.isNaN(d)) {
return d;
+ } else if (Double.isInfinite(d)) {
+ if (d < direction) {
+ return -Double.MAX_VALUE;
+ } else if (direction < d) {
+ return Double.MAX_VALUE;
+ } else {
+ return d;
+ }
} else if (d == 0) {
return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE;
}
@@ -3393,6 +3409,65 @@ public class FastMath {
}
+ /**
+ * Get the next machine representable number after a number, moving
+ * in the direction of another number.
+ *
+ * If direction
is greater than or equal tod
,
+ * the smallest machine representable number strictly greater than
+ * d
is returned; otherwise the largest representable number
+ * strictly less than d
is returned.
+ *
+ * If d
is NaN or Infinite, it is returned unchanged.
+ *
+ * @param f base number
+ * @param direction (the only important thing is whether
+ * direction is greater or smaller than f)
+ * @return the next machine representable number in the specified direction
+ */
+ public static float nextAfter(float f, float direction) {
+
+ // handling of some important special cases
+ if (Float.isNaN(f)) {
+ return f;
+ } else if (Float.isInfinite(f)) {
+ if (f < direction) {
+ return -Float.MAX_VALUE;
+ } else if (direction < f) {
+ return Float.MAX_VALUE;
+ } else {
+ return f;
+ }
+ } else if (f == 0f) {
+ return (direction < 0f) ? -Float.MIN_VALUE : Float.MIN_VALUE;
+ }
+ // special cases MAX_VALUE to infinity and MIN_VALUE to 0
+ // are handled just as normal numbers
+
+ // split the double in raw components
+ int bits = Float.floatToIntBits(f);
+ int sign = bits & 0x80000000;
+ int exponent = bits & 0x7f800000;
+ int mantissa = bits & 0x007fffff;
+
+ if (f * (direction - f) >= 0f) {
+ // we should increase the mantissa
+ if (mantissa == 0x000fffff) {
+ return Float.intBitsToFloat(sign | (exponent + 0x00800000));
+ } else {
+ return Float.intBitsToFloat(sign | exponent | (mantissa + 1));
+ }
+ } else {
+ // we should decrease the mantissa
+ if (mantissa == 0) {
+ return Float.intBitsToFloat(sign | (exponent - 0x00800000) | 0x007fffff);
+ } else {
+ return Float.intBitsToFloat(sign | exponent | (mantissa - 1));
+ }
+ }
+
+ }
+
/** Get the largest whole number smaller than x.
* @param x number from which floor is requested
* @return a double number f such that f is an integer f <= x < f + 1.0
diff --git a/src/test/java/org/apache/commons/math/util/FastMathTest.java b/src/test/java/org/apache/commons/math/util/FastMathTest.java
index 1669be2ab..ca5344db8 100644
--- a/src/test/java/org/apache/commons/math/util/FastMathTest.java
+++ b/src/test/java/org/apache/commons/math/util/FastMathTest.java
@@ -991,7 +991,7 @@ public class FastMathTest {
}
void check(Method mathMethod, double d, Object expected, Object actual, int entry){
if (!expected.equals(actual)){
- reportError(mathMethod.getName()+"(float "+d+") expected "+expected+" actual "+actual+ " entry "+entry);
+ reportError(mathMethod.getName()+"(double "+d+") expected "+expected+" actual "+actual+ " entry "+entry);
}
}
}