Here you can find the source of toDoublePow10(long m, int n)
double
representation of the specified long
number multiplied by a power of ten.
Parameter | Description |
---|---|
m | the <code>long</code> multiplier. (must be non-negative) |
n | the power of ten exponent. |
multiplier * 10n
.
private static double toDoublePow10(long m, int n)
//package com.java2s; public class Main { private static final long MASK_63 = 0x7FFFFFFFFFFFFFFFL; private static final long MASK_32 = 0xFFFFFFFFL; private static final int[] POW5_INT = { 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125 }; /**// ww w. j ava 2 s.c o m * Returns the closest <code>double</code> representation of the * specified <code>long</code> number multiplied by a power of ten. * * @param m the <code>long</code> multiplier. (must be non-negative) * @param n the power of ten exponent. * @return <code>multiplier * 10<sup>n</sup></code>. **/ private static double toDoublePow10(long m, int n) { assert m >= 0; if (m == 0) return 0.0; if (n >= 0) { // Positive power. if (n > 308) return Double.POSITIVE_INFINITY; // Works with 4 x 32 bits registers (x3:x2:x1:x0) long x0 = 0; // 32 bits. long x1 = 0; // 32 bits. long x2 = m & MASK_32; // 32 bits. long x3 = m >>> 32; // 32 bits. int pow2 = 0; while (n != 0) { int i = (n >= POW5_INT.length) ? POW5_INT.length - 1 : n; int coef = POW5_INT[i]; // 31 bits max. if (((int) x0) != 0) x0 *= coef; // 63 bits max. if (((int) x1) != 0) x1 *= coef; // 63 bits max. x2 *= coef; // 63 bits max. x3 *= coef; // 63 bits max. x1 += x0 >>> 32; x0 &= MASK_32; x2 += x1 >>> 32; x1 &= MASK_32; x3 += x2 >>> 32; x2 &= MASK_32; // Adjusts powers. pow2 += i; n -= i; // Normalizes (x3 should be 32 bits max). long carry = x3 >>> 32; if (carry != 0) { // Shift. x0 = x1; x1 = x2; x2 = x3 & MASK_32; x3 = carry; pow2 += 32; } } // Merges registers to a 63 bits mantissa. assert x3 >= 0; int shift = 31 - (Long.SIZE - Long.numberOfLeadingZeros(x3)); // -1..30 pow2 -= shift; long mantissa = (shift < 0) ? (x3 << 31) | (x2 >>> 1) : // x3 is 32 bits. (((x3 << 32) | x2) << shift) | (x1 >>> (32 - shift)); return toDoublePow2(mantissa, pow2); } else { // n < 0 if (n < -324 - 20) return 0.0; // Works with x1:x0 126 bits register. long x1 = m; // 63 bits. long x0 = 0; // 63 bits. int pow2 = 0; while (true) { // Normalizes x1:x0 int shift = 63 - (Long.SIZE - Long.numberOfLeadingZeros(x1)); x1 <<= shift; x1 |= x0 >>> (63 - shift); x0 = (x0 << shift) & MASK_63; pow2 -= shift; // Checks if division has to be performed. if (n == 0) break; // Done. // Retrieves power of 5 divisor. int i = (-n >= POW5_INT.length) ? POW5_INT.length - 1 : -n; int divisor = POW5_INT[i]; // Performs the division (126 bits by 31 bits). long wh = (x1 >>> 32); long qh = wh / divisor; long r = wh - qh * divisor; long wl = (r << 32) | (x1 & MASK_32); long ql = wl / divisor; r = wl - ql * divisor; x1 = (qh << 32) | ql; wh = (r << 31) | (x0 >>> 32); qh = wh / divisor; r = wh - qh * divisor; wl = (r << 32) | (x0 & MASK_32); ql = wl / divisor; x0 = (qh << 32) | ql; // Adjusts powers. n += i; pow2 -= i; } return toDoublePow2(x1, pow2); } } /** * Returns the closest <code>double</code> representation of the * specified <code>long</code> number multiplied by a power of two. * * @param m the <code>long</code> multiplier. (must be non-negative) * @param n the power of two exponent. * @return <code>m * 2<sup>n</sup></code>. */ private static double toDoublePow2(long m, int n) { assert m >= 0; if (m == 0) return 0.0; int bitLength = Long.SIZE - Long.numberOfLeadingZeros(m); int shift = bitLength - 53; long exp = 1023L + 52 + n + shift; // Use long to avoid overflow. if (exp >= 0x7FF) return Double.POSITIVE_INFINITY; if (exp <= 0) { // Degenerated number (subnormal, assume 0 for bit 52) if (exp <= -54) return 0.0; return toDoublePow2(m, n + 54) / 18014398509481984L; // 2^54 Exact. } // Normal number. long bits = (shift > 0) ? (m >> shift) + ((m >> (shift - 1)) & 1) : // Rounding. m << -shift; if (((bits >> 52) != 1) && (++exp >= 0x7FF)) return Double.POSITIVE_INFINITY; bits &= 0x000fffffffffffffL; // Clears MSB (bit 52) bits |= exp << 52; return Double.longBitsToDouble(bits); } }