FastMath { public static double scalb(final double d, final int n) { if ((n > -1023) && (n < 1024)) { return d * Double.longBitsToDouble(((long) (n + 1023)) << 52); } if (Double.isNaN(d) || Double.isInfinite(d) || (d == 0)) { return d; } if (n < -2098) { return (d > 0) ? 0.0 : -0.0; } if (n > 2097) { return (d > 0) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; } final long bits = Double.doubleToRawLongBits(d); final long sign = bits & 0x8000000000000000L; int exponent = ((int) (bits >>> 52)) & 0x7ff; long mantissa = bits & 0x000fffffffffffffL; int scaledExponent = exponent + n; if (n < 0) { if (scaledExponent > 0) { return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa); } else if (scaledExponent > -53) { mantissa |= 1L << 52; final long mostSignificantLostBit = mantissa & (1L << (-scaledExponent)); mantissa >>>= 1 - scaledExponent; if (mostSignificantLostBit != 0) { mantissa++; } return Double.longBitsToDouble(sign | mantissa); } else { return (sign == 0L) ? 0.0 : -0.0; } } else { if (exponent == 0) { while ((mantissa >>> 52) != 1) { mantissa <<= 1; --scaledExponent; } ++scaledExponent; mantissa &= 0x000fffffffffffffL; if (scaledExponent < 2047) { return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa); } else { return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; } } else if (scaledExponent < 2047) { return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa); } else { return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; } } } private  FastMath(); static double sqrt(final double a); static double cosh(double x); static double sinh(double x); static double tanh(double x); static double acosh(final double a); static double asinh(double a); static double atanh(double a); static double signum(final double a); static float signum(final float a); static double nextUp(final double a); static float nextUp(final float a); static double nextDown(final double a); static float nextDown(final float a); static double random(); static double exp(double x); static double expm1(double x); static double log(final double x); static double log1p(final double x); static double log10(final double x); static double log(double base, double x); static double pow(double x, double y); static double pow(double d, int e); static double sin(double x); static double cos(double x); static double tan(double x); static double atan(double x); static double atan2(double y, double x); static double asin(double x); static double acos(double x); static double cbrt(double x); static double toRadians(double x); static double toDegrees(double x); static int abs(final int x); static long abs(final long x); static float abs(final float x); static double abs(double x); static double ulp(double x); static float ulp(float x); static double scalb(final double d, final int n); static float scalb(final float f, final int n); static double nextAfter(double d, double direction); static float nextAfter(final float f, final double direction); static double floor(double x); static double ceil(double x); static double rint(double x); static long round(double x); static int round(final float x); static int min(final int a, final int b); static long min(final long a, final long b); static float min(final float a, final float b); static double min(final double a, final double b); static int max(final int a, final int b); static long max(final long a, final long b); static float max(final float a, final float b); static double max(final double a, final double b); static double hypot(final double x, final double y); static double IEEEremainder(double dividend, double divisor); static int toIntExact(final long n); static int incrementExact(final int n); static long incrementExact(final long n); static int decrementExact(final int n); static long decrementExact(final long n); static int addExact(final int a, final int b); static long addExact(final long a, final long b); static int subtractExact(final int a, final int b); static long subtractExact(final long a, final long b); static int multiplyExact(final int a, final int b); static long multiplyExact(final long a, final long b); static int floorDiv(final int a, final int b); static long floorDiv(final long a, final long b); static int floorMod(final int a, final int b); static long floorMod(final long a, final long b); static double copySign(double magnitude, double sign); static float copySign(float magnitude, float sign); static int getExponent(final double d); static int getExponent(final float f); static void main(String[] a); static final double PI; static final double E; }
@Test public void testDoubleScalbSpecialCases() { Assert.assertEquals(2.5269841324701218E-175, FastMath.scalb(2.2250738585072014E-308, 442), 0D); Assert.assertEquals(1.307993905256674E297, FastMath.scalb(1.1102230246251565E-16, 1040), 0D); Assert.assertEquals(7.2520887996488946E-217, FastMath.scalb(Double.MIN_VALUE, 356), 0D); Assert.assertEquals(8.98846567431158E307, FastMath.scalb(Double.MIN_VALUE, 2097), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb(Double.MIN_VALUE, 2098), 0D); Assert.assertEquals(1.1125369292536007E-308, FastMath.scalb(2.225073858507201E-308, -1), 0D); Assert.assertEquals(1.0E-323, FastMath.scalb(Double.MAX_VALUE, -2097), 0D); Assert.assertEquals(Double.MIN_VALUE, FastMath.scalb(Double.MAX_VALUE, -2098), 0D); Assert.assertEquals(0, FastMath.scalb(Double.MAX_VALUE, -2099), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb(Double.POSITIVE_INFINITY, -1000000), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-1.1102230246251565E-16, 1078), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-1.1102230246251565E-16, 1079), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-2.2250738585072014E-308, 2047), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-2.2250738585072014E-308, 2048), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-1.7976931348623157E308, 2147483647), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb( 1.7976931348623157E308, 2147483647), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-1.1102230246251565E-16, 2147483647), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb( 1.1102230246251565E-16, 2147483647), 0D); Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.scalb(-2.2250738585072014E-308, 2147483647), 0D); Assert.assertEquals(Double.POSITIVE_INFINITY, FastMath.scalb( 2.2250738585072014E-308, 2147483647), 0D); }
@Test public void testFloatScalbSpecialCases() { Assert.assertEquals(0f, FastMath.scalb(Float.MIN_VALUE, -30), 0F); Assert.assertEquals(2 * Float.MIN_VALUE, FastMath.scalb(Float.MIN_VALUE, 1), 0F); Assert.assertEquals(7.555786e22f, FastMath.scalb(Float.MAX_VALUE, -52), 0F); Assert.assertEquals(1.7014118e38f, FastMath.scalb(Float.MIN_VALUE, 276), 0F); Assert.assertEquals(Float.POSITIVE_INFINITY, FastMath.scalb(Float.MIN_VALUE, 277), 0F); Assert.assertEquals(5.8774718e-39f, FastMath.scalb(1.1754944e-38f, -1), 0F); Assert.assertEquals(2 * Float.MIN_VALUE, FastMath.scalb(Float.MAX_VALUE, -276), 0F); Assert.assertEquals(Float.MIN_VALUE, FastMath.scalb(Float.MAX_VALUE, -277), 0F); Assert.assertEquals(0, FastMath.scalb(Float.MAX_VALUE, -278), 0F); Assert.assertEquals(Float.POSITIVE_INFINITY, FastMath.scalb(Float.POSITIVE_INFINITY, -1000000), 0F); Assert.assertEquals(-3.13994498e38f, FastMath.scalb(-1.1e-7f, 151), 0F); Assert.assertEquals(Float.NEGATIVE_INFINITY, FastMath.scalb(-1.1e-7f, 152), 0F); Assert.assertEquals(Float.POSITIVE_INFINITY, FastMath.scalb(3.4028235E38f, 2147483647), 0F); Assert.assertEquals(Float.NEGATIVE_INFINITY, FastMath.scalb(-3.4028235E38f, 2147483647), 0F); }