JDK-4826652 : Add copySign, nextAfter, nextUp, scalb, ilogb, etc. to Math and StrictMath
Type:Enhancement
Component:core-libs
Sub-Component:java.lang
Affected Version:1.3.0,5.0
Priority:P4
Status:Resolved
Resolution:Fixed
OS:generic
CPU:generic
Submitted:2003-03-04
Updated:2024-09-13
Resolved:2005-08-20
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
First portion of work for 4406429 "RFE: Add IEEE 754 Recommended Functions to Math, StrictMath."
Comments
EVALUATION
Added methods
copySign
getExponent
nextAfter
nextUp
scalb
for float and double arguments to the Math and StrictMath classes. In addition, constants for MIN_NORMAL, MAX_EXPONENT, and MIN_EXPONENT were added to Float and Double.
25-10-2005
SUGGESTED FIX
src/share/classes/java/lang>sccs sccsdiff -r1.27 -r1.28 StrictMath.jav>
------- StrictMath.java -------
1085a1086
> * @since 1.5
1116a1118
> * @since 1.5
1118a1121,1401
>
> /**
> * Returns the first floating-point argument with the sign of the
> * second floating-point argument. For this method, a NaN
> * {@code sign} argument is always treated as if it were
> * positive.
> *
> * @param magnitude the parameter providing the magnitude of the result
> * @param sign the parameter providing the sign of the result
> * @return a value with the magnitude of {@code magnitude}
> * and the sign of {@code sign}.
> * @since 1.6
> */
> public static double copySign(double magnitude, double sign) {
> return sun.misc.FpUtils.copySign(magnitude, sign);
> }
>
> /**
> * Returns the first floating-point argument with the sign of the
> * second floating-point argument. For this method, a NaN
> * {@code sign} argument is always treated as if it were
> * positive.
> *
> * @param magnitude the parameter providing the magnitude of the result
> * @param sign the parameter providing the sign of the result
> * @return a value with the magnitude of {@code magnitude}
> * and the sign of {@code sign}.
> * @since 1.6
> */
> public static float copySign(float magnitude, float sign) {
> return sun.misc.FpUtils.copySign(magnitude, sign);
> }
> /**
> * Returns the unbiased exponent used in the representation of a
> * {@code float}. Special cases:
> *
> * <ul>
> * <li>If the argument is NaN or infinite, then the result is
> * {@link Float#MAX_EXPONENT} + 1.
> * <li>If the argument is zero or subnormal, then the result is
> * {@link Float#MIN_EXPONENT} -1.
> * </ul>
> * @param f a {@code float} value
> * @since 1.6
> */
> public static int getExponent(float f) {
> return sun.misc.FpUtils.getExponent(f);
> }
>
> /**
> * Returns the unbiased exponent used in the representation of a
> * {@code double}. Special cases:
> *
> * <ul>
> * <li>If the argument is NaN or infinite, then the result is
> * {@link Double#MAX_EXPONENT} + 1.
> * <li>If the argument is zero or subnormal, then the result is
> * {@link Double#MIN_EXPONENT} -1.
> * </ul>
> * @param d a {@code double} value
> * @since 1.6
> */
> public static int getExponent(double d) {
> return sun.misc.FpUtils.getExponent(d);
> }
>
> /**
> * Returns the floating-point number adjacent to the first
> * argument in the direction of the second argument. If both
> * arguments compare as equal the second argument is returned.
> *
> * <p>
> * Special cases:
> * <ul>
> * <li> If either argument is a NaN, then NaN is returned.
> *
> * <li> If both arguments are signed zeros, {@code direction}
> * is returned unchanged (as implied by the requirement of
> * returning the second argument if the arguments compare as
> * equal).
> *
> * <li> If {@code start} is
> * ±{@link Double#MIN_VALUE} and {@code direction}
> * has a value such that the result should have a smaller
> * magnitude, then a zero with the same sign as {@code start}
> * is returned.
> *
> * <li> If {@code start} is infinite and
> * {@code direction} has a value such that the result should
> * have a smaller magnitude, {@link Double#MAX_VALUE} with the
> * same sign as {@code start} is returned.
> *
> * <li> If {@code start} is equal to ±
> * {@link Double#MAX_VALUE} and {@code direction} has a
> * value such that the result should have a larger magnitude, an
> * infinity with same sign as {@code start} is returned.
> * </ul>
> *
> * @param start starting floating-point value
> * @param direction value indicating which of
> * {@code start}'s neighbors or {@code start} should
> * be returned
> * @return The floating-point number adjacent to {@code start} in the
> * direction of {@code direction}.
> * @since 1.6
> */
> public static double nextAfter(double start, double direction) {
> return sun.misc.FpUtils.nextAfter(start, direction);
> }
>
> /**
> * Returns the floating-point number adjacent to the first
> * argument in the direction of the second argument. If both
> * arguments compare as equal a value equivalent to the second argument
> * is returned.
> *
> * <p>
> * Special cases:
> * <ul>
> * <li> If either argument is a NaN, then NaN is returned.
> *
> * <li> If both arguments are signed zeros, a value equivalent
> * to {@code direction} is returned.
> *
> * <li> If {@code start} is
> * ±{@link Float#MIN_VALUE} and {@code direction}
> * has a value such that the result should have a smaller
> * magnitude, then a zero with the same sign as {@code start}
> * is returned.
> *
> * <li> If {@code start} is infinite and
> * {@code direction} has a value such that the result should
> * have a smaller magnitude, {@link Float#MAX_VALUE} with the
> * same sign as {@code start} is returned.
> *
> * <li> If {@code start} is equal to ±
> * {@link Float#MAX_VALUE} and {@code direction} has a
> * value such that the result should have a larger magnitude, an
> * infinity with same sign as {@code start} is returned.
> * </ul>
> *
> * @param start starting floating-point value
> * @param direction value indicating which of
> * {@code start}'s neighbors or {@code start} should
> * be returned
> * @return The floating-point number adjacent to {@code start} in the
> * direction of {@code direction}.
> * @since 1.6
> */
> public static float nextAfter(float start, double direction) {
> return sun.misc.FpUtils.nextAfter(start, direction);
> }
>
> /**
> * Returns the floating-point value adjacent to {@code d} in
> * the direction of positive infinity. This method is
> * semantically equivalent to {@code nextAfter(d,
> * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
> * implementation may run faster than its equivalent
> * {@code nextAfter} call.
> *
> * <p>Special Cases:
> * <ul>
> * <li> If the argument is NaN, the result is NaN.
> *
> * <li> If the argument is positive infinity, the result is
> * positive infinity.
> *
> * <li> If the argument is zero, the result is
> * {@link Double#MIN_VALUE}
> *
> * </ul>
> *
> * @param d starting floating-point value
> * @return The adjacent floating-point value closer to positive
> * infinity.
> * @since 1.6
> */
> public static double nextUp(double d) {
> return sun.misc.FpUtils.nextUp(d);
> }
>
> /**
> * Returns the floating-point value adjacent to {@code f} in
> * the direction of positive infinity. This method is
> * semantically equivalent to {@code nextAfter(f,
> * Float.POSITIVE_INFINITY)}; however, a {@code nextUp}
> * implementation may run faster than its equivalent
> * {@code nextAfter} call.
> *
> * <p>Special Cases:
> * <ul>
> * <li> If the argument is NaN, the result is NaN.
> *
> * <li> If the argument is positive infinity, the result is
> * positive infinity.
> *
> * <li> If the argument is zero, the result is
> * {@link Float#MIN_VALUE}
> *
> * </ul>
> *
> * @param f starting floating-point value
> * @return The adjacent floating-point value closer to positive
> * infinity.
> * @since 1.6
> */
> public static float nextUp(float f) {
> return sun.misc.FpUtils.nextUp(f);
> }
>
>
> /**
> * Return {@code d} ×
> * 2<sup>{@code scaleFactor}</sup> rounded as if performed
> * by a single correctly rounded floating-point multiply to a
> * member of the double value set. See the Java
> * Language Specification for a discussion of floating-point
> * value sets. If the exponent of the result is between {@link
> * Double#MIN_EXPONENT} and {@link Double#MAX_EXPONENT}, the
> * answer is calculated exactly. If the exponent of the result
> * would be larger than {@code Double.MAX_EXPONENT}, an
> * infinity is returned. Note that if the result is subnormal,
> * precision may be lost; that is, when {@code scalb(x, n)}
> * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
> * <i>x</i>. When the result is non-NaN, the result has the same
> * sign as {@code d}.
> *
> *<p>
> * Special cases:
> * <ul>
> * <li> If the first argument is NaN, NaN is returned.
> * <li> If the first argument is infinite, then an infinity of the
> * same sign is returned.
> * <li> If the first argument is zero, then a zero of the same
> * sign is returned.
> * </ul>
> *
> * @param d number to be scaled by a power of two.
> * @param scaleFactor power of 2 used to scale {@code d}
> * @return {@code d} × 2<sup>{@code scaleFactor}</sup>
> * @since 1.6
> */
> public static double scalb(double d, int scaleFactor) {
> return sun.misc.FpUtils.scalb(d, scaleFactor);
> }
>
> /**
> * Return {@code f} ×
> * 2<sup>{@code scaleFactor}</sup> rounded as if performed
> * by a single correctly rounded floating-point multiply to a
> * member of the float value set. See the Java
> * Language Specification for a discussion of floating-point
> * value sets. If the exponent of the result is between {@link
> * Float#MIN_EXPONENT} and {@link Float#MAX_EXPONENT}, the
> * answer is calculated exactly. If the exponent of the result
> * would be larger than {@code Float.MAX_EXPONENT}, an
> * infinity is returned. Note that if the result is subnormal,
> * precision may be lost; that is, when {@code scalb(x, n)}
> * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
> * <i>x</i>. When the result is non-NaN, the result has the same
> * sign as {@code f}.
> *
> *<p>
> * Special cases:
> * <ul>
> * <li> If the first argument is NaN, NaN is returned.
> * <li> If the first argument is infinite, then an infinity of the
> * same sign is returned.
> * <li> If the first argument is zero, then a zero of the same
> * sign is returned.
> * </ul>
> *
> * @param f number to be scaled by a power of two.
> * @param scaleFactor power of 2 used to scale {@code f}
> * @return {@code f} × 2<sup>{@code scaleFactor}</sup>
> * @since 1.6
> */
> public static float scalb(float f, int scaleFactor) {
> return sun.misc.FpUtils.scalb(f, scaleFactor);
> }
12-08-2005
SUGGESTED FIX
src/share/classes/java/lang>sccs sccsdiff -r1.95 -r1.96 Float.java
------- Float.java -------
64a65,74
> * A constant holding the smallest positive normal value of type
> * {@code float}, 2<sup>-126</sup>. It is equal to the
> * hexadecimal floating-point literal {@code 0x1.0p-126f} and also
> * equal to {@code Float.intBitsToFloat(0x00800000)}.
> *
> * @since 1.6
> */
> public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f
>
> /**
72a83,100
> * Maximum exponent a finite {@code float} variable may have. It
> * is equal to the value returned by {@code
> * Math.getExponent(Float.MAX_VALUE)}.
> *
> * @since 1.6
> */
> public static final int MAX_EXPONENT = 127;
>
> /**
> * Minimum exponent a normalized {@code float} variable may have.
> * It is equal to the value returned by {@code
> * Math.getExponent(Float.MIN_NORMAL)}.
> *
> * @since 1.6
> */
> public static final int MIN_EXPONENT = -126;
>
> /**
src/share/classes/java/lang>sccs sccsdiff -r1.95 -r1.96 Double.java
------- Double.java -------
64a65,74
> * A constant holding the smallest positive normal value of type
> * {@code double}, 2<sup>-1022</sup>. It is equal to the
> * hexadecimal floating-point literal {@code 0x1.0p-1022} and also
> * equal to {@code Double.longBitsToDouble(0x0010000000000000L)}.
> *
> * @since 1.6
> */
> public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
>
> /**
73a84,101
> * Maximum exponent a finite {@code double} variable may have.
> * It is equal to the value returned by
> * {@code Math.getExponent(Double.MAX_VALUE)}.
> *
> * @since 1.6
> */
> public static final int MAX_EXPONENT = 1023;
>
> /**
> * Minimum exponent a normalized {@code double} variable may
> * have. It is equal to the value returned by
> * {@code Math.getExponent(Double.MIN_NORMAL)}.
> *
> * @since 1.6
> */
> public static final int MIN_EXPONENT = -1022;
>
> /**
src/share/classes/java/lang>sccs sccsdiff -r1.70 -r1.71 Math.java
------- Math.java -------
1180a1181
> * @since 1.5
1216a1218
> * @since 1.5
1220a1223,1512
>
> /**
> * Returns the first floating-point argument with the sign of the
> * second floating-point argument. Note that unlike the {@link
> * StrictMath#copySign(double, double) StrictMath.copySign}
> * method, this method does not require NaN <code>sign</code>
> * arguments to be treated as positive values; implementations are
> * permitted to treat some NaN arguments as positive and other NaN
> * arguments as negative to allow greater performance.
> *
> * @param magnitude the parameter providing the magnitude of the result
> * @param sign the parameter providing the sign of the result
> * @return a value with the magnitude of <code>magnitude</code>
> * and the sign of <code>sign</code>.
> * @since 1.6
> */
> public static double copySign(double magnitude, double sign) {
> return sun.misc.FpUtils.rawCopySign(magnitude, sign);
> }
>
> /**
> * Returns the first floating-point argument with the sign of the
> * second floating-point argument. Note that unlike the {@link
> * StrictMath#copySign(float, float) StrictMath.copySign}
> * method, this method does not require NaN <code>sign</code>
> * arguments to be treated as positive values; implementations are
> * permitted to treat some NaN arguments as positive and other NaN
> * arguments as negative to allow greater performance.
> *
> * @param magnitude the parameter providing the magnitude of the result
> * @param sign the parameter providing the sign of the result
> * @return a value with the magnitude of <code>magnitude</code>
> * and the sign of <code>sign</code>.
> * @since 1.6
> */
> public static float copySign(float magnitude, float sign) {
> return sun.misc.FpUtils.rawCopySign(magnitude, sign);
> }
>
> /**
> * Returns the unbiased exponent used in the representation of a
> * {@code float}. Special cases:
> *
> * <ul>
> * <li>If the argument is NaN or infinite, then the result is
> * {@link Float#MAX_EXPONENT} + 1.
> * <li>If the argument is zero or subnormal, then the result is
> * {@link Float#MIN_EXPONENT} -1.
> * </ul>
> * @param f a {@code float} value
> * @return the unbiased exponent of the argument
> * @since 1.6
> */
> public static int getExponent(float f) {
> return sun.misc.FpUtils.getExponent(f);
> }
>
> /**
> * Returns the unbiased exponent used in the representation of a
> * {@code double}. Special cases:
> *
> * <ul>
> * <li>If the argument is NaN or infinite, then the result is
> * {@link Double#MAX_EXPONENT} + 1.
> * <li>If the argument is zero or subnormal, then the result is
> * {@link Double#MIN_EXPONENT} -1.
> * </ul>
> * @param d a {@code double} value
> * @return the unbiased exponent of the argument
> * @since 1.6
> */
> public static int getExponent(double d) {
> return sun.misc.FpUtils.getExponent(d);
> }
>
> /**
> * Returns the floating-point number adjacent to the first
> * argument in the direction of the second argument. If both
> * arguments compare as equal the second argument is returned.
> *
> * <p>
> * Special cases:
> * <ul>
> * <li> If either argument is a NaN, then NaN is returned.
> *
> * <li> If both arguments are signed zeros, {@code direction}
> * is returned unchanged (as implied by the requirement of
> * returning the second argument if the arguments compare as
> * equal).
> *
> * <li> If {@code start} is
> * ±{@link Double#MIN_VALUE} and {@code direction}
> * has a value such that the result should have a smaller
> * magnitude, then a zero with the same sign as {@code start}
> * is returned.
> *
> * <li> If {@code start} is infinite and
> * {@code direction} has a value such that the result should
> * have a smaller magnitude, {@link Double#MAX_VALUE} with the
> * same sign as {@code start} is returned.
> *
> * <li> If {@code start} is equal to ±
> * {@link Double#MAX_VALUE} and {@code direction} has a
> * value such that the result should have a larger magnitude, an
> * infinity with same sign as {@code start} is returned.
> * </ul>
> *
> * @param start starting floating-point value
> * @param direction value indicating which of
> * {@code start}'s neighbors or {@code start} should
> * be returned
> * @return The floating-point number adjacent to {@code start} in the
> * direction of {@code direction}.
> * @since 1.6
> */
> public static double nextAfter(double start, double direction) {
> return sun.misc.FpUtils.nextAfter(start, direction);
> }
>
> /**
> * Returns the floating-point number adjacent to the first
> * argument in the direction of the second argument. If both
> * arguments compare as equal a value equivalent to the second argument
> * is returned.
> *
> * <p>
> * Special cases:
> * <ul>
> * <li> If either argument is a NaN, then NaN is returned.
> *
> * <li> If both arguments are signed zeros, a value equivalent
> * to {@code direction} is returned.
> *
> * <li> If {@code start} is
> * ±{@link Float#MIN_VALUE} and {@code direction}
> * has a value such that the result should have a smaller
> * magnitude, then a zero with the same sign as {@code start}
> * is returned.
> *
> * <li> If {@code start} is infinite and
> * {@code direction} has a value such that the result should
> * have a smaller magnitude, {@link Float#MAX_VALUE} with the
> * same sign as {@code start} is returned.
> *
> * <li> If {@code start} is equal to ±
> * {@link Float#MAX_VALUE} and {@code direction} has a
> * value such that the result should have a larger magnitude, an
> * infinity with same sign as {@code start} is returned.
> * </ul>
> *
> * @param start starting floating-point value
> * @param direction value indicating which of
> * {@code start}'s neighbors or {@code start} should
> * be returned
> * @return The floating-point number adjacent to {@code start} in the
> * direction of {@code direction}.
> * @since 1.6
> */
> public static float nextAfter(float start, double direction) {
> return sun.misc.FpUtils.nextAfter(start, direction);
> }
>
> /**
> * Returns the floating-point value adjacent to {@code d} in
> * the direction of positive infinity. This method is
> * semantically equivalent to {@code nextAfter(d,
> * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
> * implementation may run faster than its equivalent
> * {@code nextAfter} call.
> *
> * <p>Special Cases:
> * <ul>
> * <li> If the argument is NaN, the result is NaN.
> *
> * <li> If the argument is positive infinity, the result is
> * positive infinity.
> *
> * <li> If the argument is zero, the result is
> * {@link Double#MIN_VALUE}
> *
> * </ul>
> *
> * @param d starting floating-point value
> * @return The adjacent floating-point value closer to positive
> * infinity.
> * @since 1.6
> */
> public static double nextUp(double d) {
> return sun.misc.FpUtils.nextUp(d);
> }
>
> /**
> * Returns the floating-point value adjacent to {@code f} in
> * the direction of positive infinity. This method is
> * semantically equivalent to {@code nextAfter(f,
> * Float.POSITIVE_INFINITY)}; however, a {@code nextUp}
> * implementation may run faster than its equivalent
> * {@code nextAfter} call.
> *
> * <p>Special Cases:
> * <ul>
> * <li> If the argument is NaN, the result is NaN.
> *
> * <li> If the argument is positive infinity, the result is
> * positive infinity.
> *
> * <li> If the argument is zero, the result is
> * {@link Float#MIN_VALUE}
> *
> * </ul>
> *
> * @param f starting floating-point value
> * @return The adjacent floating-point value closer to positive
> * infinity.
> * @since 1.6
> */
> public static float nextUp(float f) {
> return sun.misc.FpUtils.nextUp(f);
> }
>
>
> /**
> * Return {@code d} ×
> * 2<sup>{@code scaleFactor}</sup> rounded as if performed
> * by a single correctly rounded floating-point multiply to a
> * member of the double value set. See the Java
> * Language Specification for a discussion of floating-point
> * value sets. If the exponent of the result is between {@link
> * Double#MIN_EXPONENT} and {@link Double#MAX_EXPONENT}, the
> * answer is calculated exactly. If the exponent of the result
> * would be larger than {@code Double.MAX_EXPONENT}, an
> * infinity is returned. Note that if the result is subnormal,
> * precision may be lost; that is, when {@code scalb(x, n)}
> * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
> * <i>x</i>. When the result is non-NaN, the result has the same
> * sign as {@code d}.
> *
> *<p>
> * Special cases:
> * <ul>
> * <li> If the first argument is NaN, NaN is returned.
> * <li> If the first argument is infinite, then an infinity of the
> * same sign is returned.
> * <li> If the first argument is zero, then a zero of the same
> * sign is returned.
> * </ul>
> *
> * @param d number to be scaled by a power of two.
> * @param scaleFactor power of 2 used to scale {@code d}
> * @return {@code d} × 2<sup>{@code scaleFactor}</sup>
> * @since 1.6
> */
> public static double scalb(double d, int scaleFactor) {
> return sun.misc.FpUtils.scalb(d, scaleFactor);
> }
>
> /**
> * Return {@code f} ×
> * 2<sup>{@code scaleFactor}</sup> rounded as if performed
> * by a single correctly rounded floating-point multiply to a
> * member of the float value set. See the Java
> * Language Specification for a discussion of floating-point
> * value sets. If the exponent of the result is between {@link
> * Float#MIN_EXPONENT} and {@link Float#MAX_EXPONENT}, the
> * answer is calculated exactly. If the exponent of the result
> * would be larger than {@code Float.MAX_EXPONENT}, an
> * infinity is returned. Note that if the result is subnormal,
> * precision may be lost; that is, when {@code scalb(x, n)}
> * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
> * <i>x</i>. When the result is non-NaN, the result has the same
> * sign as {@code f}.
> *
> *<p>
> * Special cases:
> * <ul>
> * <li> If the first argument is NaN, NaN is returned.
> * <li> If the first argument is infinite, then an infinity of the
> * same sign is returned.
> * <li> If the first argument is zero, then a zero of the same
> * sign is returned.
> * </ul>
> *
> * @param f number to be scaled by a power of two.
> * @param scaleFactor power of 2 used to scale {@code f}
> * @return {@code f} × 2<sup>{@code scaleFactor}</sup>
> * @since 1.6
> */
> public static float scalb(float f, int scaleFactor) {
> return sun.misc.FpUtils.scalb(f, scaleFactor);
> }
src/share/classes/java/lang>sccs sccsdiff -r1.27 -r1.28 StrictMath.jav>
12-08-2005
EVALUATION
Initial work needed to address 4406429.
###@###.### 2003-03-03