in commons-math-core/src/main/java/org/apache/commons/math4/core/jdkmath/AccurateMath.java [3166:3239]
public static float scalb(final float f, final int n) {
// first simple and fast handling when 2^n can be represented using normal numbers
if ((n > -127) && (n < 128)) {
return f * Float.intBitsToFloat((n + 127) << 23);
}
// handle special cases
if (Float.isNaN(f) || Float.isInfinite(f) || (f == 0f)) {
return f;
}
if (n < -277) {
return (f > 0) ? 0.0f : -0.0f;
}
if (n > 276) {
return (f > 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
}
// decompose f
final int bits = Float.floatToIntBits(f);
final int sign = bits & 0x80000000;
int exponent = (bits >>> 23) & 0xff;
int mantissa = bits & 0x007fffff;
// compute scaled exponent
int scaledExponent = exponent + n;
if (n < 0) {
// we are really in the case n <= -127
if (scaledExponent > 0) {
// both the input and the result are normal numbers, we only adjust the exponent
return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
} else if (scaledExponent > -24) {
// the input is a normal number and the result is a subnormal number
// recover the hidden mantissa bit
mantissa |= 1 << 23;
// scales down complete mantissa, hence losing least significant bits
final int mostSignificantLostBit = mantissa & (1 << (-scaledExponent));
mantissa >>>= 1 - scaledExponent;
if (mostSignificantLostBit != 0) {
// we need to add 1 bit to round up the result
mantissa++;
}
return Float.intBitsToFloat(sign | mantissa);
} else {
// no need to compute the mantissa, the number scales down to 0
return (sign == 0) ? 0.0f : -0.0f;
}
} else {
// we are really in the case n >= 128
if (exponent == 0) {
// the input number is subnormal, normalize it
while ((mantissa >>> 23) != 1) {
mantissa <<= 1;
--scaledExponent;
}
++scaledExponent;
mantissa &= 0x007fffff;
if (scaledExponent < 255) {
return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
} else {
return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
}
} else if (scaledExponent < 255) {
return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
} else {
return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
}
}
}