Java Double Number From toDoublePow10(long m, int n)

Here you can find the source of toDoublePow10(long m, int n)

Description

Returns the closest double representation of the specified long number multiplied by a power of ten.

License

Open Source License

Parameter

Parameter Description
m the <code>long</code> multiplier. (must be non-negative)
n the power of ten exponent.

Return

multiplier * 10n.

Declaration

private static double toDoublePow10(long m, int n) 

Method Source Code

//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);
    }
}

Related

  1. toDoubleAsUnsigned(long v)
  2. toDoubleByObject(Object obj)
  3. toDoubleDigit(int number)
  4. toDoubleMatrix(Number[][] matrix)
  5. toDoubleObject(Object obj)
  6. toDoublePow2(long m, int n)
  7. toDoublePrecision(long fixedPrecisionOrdinate)
  8. toDoublePrimitiveArray(final Double[] wrappedArray)
  9. toDoubleQuotes(String str)