⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtoa.java

📁 javascript语言的解释器源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package org.mozilla.javascript;import java.math.BigInteger;class DToA {	public static void main(String[] args) {		DToA dt=new DToA();		for(int i=0;i<18;i++)		{			System.out.println(DToA.BASEDIGIT(i));					}			}/* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce, * which occurs when printing -5e-324 in binary.  We could compute a better estimate of the size of * the output string and malloc fewer bytes depending on d and base, but why bother? */    private static final int DTOBASESTR_BUFFER_SIZE = 1078;    private static char BASEDIGIT(int digit) {        return (char)((digit >= 10) ? 'a' - 10 + digit : '0' + digit);    }    static final int        DTOSTR_STANDARD = 0,              /* Either fixed or exponential format; round-trip */        DTOSTR_STANDARD_EXPONENTIAL = 1,  /* Always exponential format; round-trip */        DTOSTR_FIXED = 2,                 /* Round to <precision> digits after the decimal point; exponential if number is large */        DTOSTR_EXPONENTIAL = 3,           /* Always exponential format; <precision> significant digits */        DTOSTR_PRECISION = 4;             /* Either fixed or exponential format; <precision> significant digits */    private static final int Frac_mask = 0xfffff;    private static final int Exp_shift = 20;    private static final int Exp_msk1 = 0x100000;    private static final long Frac_maskL = 0xfffffffffffffL;    private static final int Exp_shiftL = 52;    private static final long Exp_msk1L = 0x10000000000000L;    private static final int Bias = 1023;    private static final int P = 53;    private static final int Exp_shift1 = 20;    private static final int Exp_mask  = 0x7ff00000;    private static final int Exp_mask_shifted = 0x7ff;    private static final int Bndry_mask  = 0xfffff;    private static final int Log2P = 1;    private static final int Sign_bit = 0x80000000;    private static final int Exp_11  = 0x3ff00000;    private static final int Ten_pmax = 22;    private static final int Quick_max = 14;    private static final int Bletch = 0x10;    private static final int Frac_mask1 = 0xfffff;    private static final int Int_max = 14;    private static final int n_bigtens = 5;    private static final double tens[] = {        1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,        1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,        1e20, 1e21, 1e22    };    private static final double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };    private static int lo0bits(int y)    {        int k;        int x = y;        if ((x & 7) != 0) {            if ((x & 1) != 0)                return 0;            if ((x & 2) != 0) {                return 1;            }            return 2;        }        k = 0;        if ((x & 0xffff) == 0) {            k = 16;            x >>>= 16;        }        if ((x & 0xff) == 0) {            k += 8;            x >>>= 8;        }        if ((x & 0xf) == 0) {            k += 4;            x >>>= 4;        }        if ((x & 0x3) == 0) {            k += 2;            x >>>= 2;        }        if ((x & 1) == 0) {            k++;            x >>>= 1;            if ((x & 1) == 0)                return 32;        }        return k;    }    /* Return the number (0 through 32) of most significant zero bits in x. */    private static int hi0bits(int x)    {        int k = 0;        if ((x & 0xffff0000) == 0) {            k = 16;            x <<= 16;        }        if ((x & 0xff000000) == 0) {            k += 8;            x <<= 8;        }        if ((x & 0xf0000000) == 0) {            k += 4;            x <<= 4;        }        if ((x & 0xc0000000) == 0) {            k += 2;            x <<= 2;        }        if ((x & 0x80000000) == 0) {            k++;            if ((x & 0x40000000) == 0)                return 32;        }        return k;    }    private static void stuffBits(byte bits[], int offset, int val)    {        bits[offset] = (byte)(val >> 24);        bits[offset + 1] = (byte)(val >> 16);        bits[offset + 2] = (byte)(val >> 8);        bits[offset + 3] = (byte)(val);    }    /* Convert d into the form b*2^e, where b is an odd integer.  b is the returned     * Bigint and e is the returned binary exponent.  Return the number of significant     * bits in b in bits.  d must be finite and nonzero. */    private static BigInteger d2b(double d, int[] e, int[] bits)    {        byte dbl_bits[];        int i, k, y, z, de;        long dBits = Double.doubleToLongBits(d);        int d0 = (int)(dBits >>> 32);        int d1 = (int)(dBits);        z = d0 & Frac_mask;        d0 &= 0x7fffffff;   /* clear sign bit, which we ignore */        if ((de = (int)(d0 >>> Exp_shift)) != 0)            z |= Exp_msk1;        if ((y = d1) != 0) {            dbl_bits = new byte[8];            k = lo0bits(y);            y >>>= k;            if (k != 0) {                stuffBits(dbl_bits, 4, y | z << (32 - k));                z >>= k;            }            else                stuffBits(dbl_bits, 4, y);            stuffBits(dbl_bits, 0, z);            i = (z != 0) ? 2 : 1;        }        else {    //        JS_ASSERT(z);            dbl_bits = new byte[4];            k = lo0bits(z);            z >>>= k;            stuffBits(dbl_bits, 0, z);            k += 32;            i = 1;        }        if (de != 0) {            e[0] = de - Bias - (P-1) + k;            bits[0] = P - k;        }        else {            e[0] = de - Bias - (P-1) + 1 + k;            bits[0] = 32*i - hi0bits(z);        }        return new BigInteger(dbl_bits);    }    static String JS_dtobasestr(int base, double d)    {        if (!(2 <= base && base <= 36))            throw new IllegalArgumentException("Bad base: "+base);        /* Check for Infinity and NaN */        if (Double.isNaN(d)) {            return "NaN";        } else if (Double.isInfinite(d)) {            return (d > 0.0) ? "Infinity" : "-Infinity";        } else if (d == 0) {            // ALERT: should it distinguish -0.0 from +0.0 ?            return "0";        }        boolean negative;        if (d >= 0.0) {            negative = false;        } else {            negative = true;            d = -d;        }        /* Get the integer part of d including '-' sign. */        String intDigits;        double dfloor = Math.floor(d);        long lfloor = (long)dfloor;        if (lfloor == dfloor) {            // int part fits long            intDigits = Long.toString((negative) ? -lfloor : lfloor, base);        } else {            // BigInteger should be used            long floorBits = Double.doubleToLongBits(dfloor);            int exp = (int)(floorBits >> Exp_shiftL) & Exp_mask_shifted;            long mantissa;            if (exp == 0) {                mantissa = (floorBits & Frac_maskL) << 1;            } else {                mantissa = (floorBits & Frac_maskL) | Exp_msk1L;            }            if (negative) {                mantissa = -mantissa;            }            exp -= 1075;            BigInteger x = BigInteger.valueOf(mantissa);            if (exp > 0) {                x = x.shiftLeft(exp);            } else if (exp < 0) {                x = x.shiftRight(-exp);            }            intDigits = x.toString(base);        }        if (d == dfloor) {            // No fraction part            return intDigits;        } else {            /* We have a fraction. */            char[] buffer;       /* The output string */            int p;               /* index to current position in the buffer */            int q;            int digit;            double df;           /* The fractional part of d */            BigInteger b;            buffer = new char[DTOBASESTR_BUFFER_SIZE];            p = 0;            df = d - dfloor;            long dBits = Double.doubleToLongBits(d);            int word0 = (int)(dBits >> 32);            int word1 = (int)(dBits);            int[] e = new int[1];            int[] bbits = new int[1];            b = d2b(df, e, bbits);//            JS_ASSERT(e < 0);            /* At this point df = b * 2^e.  e must be less than zero because 0 < df < 1. */            int s2 = -(word0 >>> Exp_shift1 & Exp_mask >> Exp_shift1);            if (s2 == 0)                s2 = -1;            s2 += Bias + P;            /* 1/2^s2 = (nextDouble(d) - d)/2 *///            JS_ASSERT(-s2 < e);            BigInteger mlo = BigInteger.valueOf(1);            BigInteger mhi = mlo;            if ((word1 == 0) && ((word0 & Bndry_mask) == 0)                && ((word0 & (Exp_mask & Exp_mask << 1)) != 0)) {                /* The special case.  Here we want to be within a quarter of the last input                   significant digit instead of one half of it when the output string's value is less than d.  */                s2 += Log2P;                mhi = BigInteger.valueOf(1<<Log2P);            }            b = b.shiftLeft(e[0] + s2);            BigInteger s = BigInteger.valueOf(1);            s = s.shiftLeft(s2);            /* At this point we have the following:             *   s = 2^s2;             *   1 > df = b/2^s2 > 0;             *   (d - prevDouble(d))/2 = mlo/2^s2;             *   (nextDouble(d) - d)/2 = mhi/2^s2. */            BigInteger bigBase = BigInteger.valueOf(base);            boolean done = false;            do {                b = b.multiply(bigBase);                BigInteger[] divResult = b.divideAndRemainder(s);                b = divResult[1];                digit = (char)(divResult[0].intValue());                if (mlo == mhi)                    mlo = mhi = mlo.multiply(bigBase);                else {                    mlo = mlo.multiply(bigBase);                    mhi = mhi.multiply(bigBase);                }                /* Do we yet have the shortest string that will round to d? */                int j = b.compareTo(mlo);                /* j is b/2^s2 compared with mlo/2^s2. */                BigInteger delta = s.subtract(mhi);                int j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta);                /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */                if (j1 == 0 && ((word1 & 1) == 0)) {                    if (j > 0)                        digit++;                    done = true;                } else                if (j < 0 || (j == 0 && ((word1 & 1) == 0))) {                    if (j1 > 0) {                        /* Either dig or dig+1 would work here as the least significant digit.                           Use whichever would produce an output value closer to d. */                        b = b.shiftLeft(1);                        j1 = b.compareTo(s);                        if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output                                     * such as 3.5 in base 3.  */                            digit++;                    }                    done = true;                } else if (j1 > 0) {                    digit++;                    done = true;                }//                JS_ASSERT(digit < (uint32)base);                buffer[p++] = BASEDIGIT(digit);            } while (!done);            StringBuffer sb = new StringBuffer(intDigits.length() + 1 + p);            sb.append(intDigits);            sb.append('.');            sb.append(buffer, 0, p);            return sb.toString();        }    }    /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.     *     * Inspired by "How to Print Floating-Point Numbers Accurately" by     * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].     *     * Modifications:     *  1. Rather than iterating, we use a simple numeric overestimate     *     to determine k = floor(log10(d)).  We scale relevant     *     quantities using O(log2(k)) rather than O(k) multiplications.     *  2. For some modes > 2 (corresponding to ecvt and fcvt), we don't     *     try to generate digits strictly left to right.  Instead, we     *     compute with fewer bits and propagate the carry if necessary     *     when rounding the final digit up.  This is often faster.     *  3. Under the assumption that input will be rounded nearest,     *     mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.     *     That is, we allow equality in stopping tests when the     *     round-nearest rule will give the same floating-point value     *     as would satisfaction of the stopping test with strict     *     inequality.     *  4. We remove common factors of powers of 2 from relevant     *     quantities.     *  5. When converting floating-point integers less than 1e16,     *     we use floating-point arithmetic rather than resorting     *     to multiple-precision integers.     *  6. When asked to produce fewer than 15 digits, we first try     *     to get by with floating-point arithmetic; we resort to     *     multiple-precision integer arithmetic only if we cannot     *     guarantee that the floating-point calculation has given     *     the correctly rounded result.  For k requested digits and     *     "uniformly" distributed input, the probability is     *     something like 10^(k-15) that we must resort to the Long     *     calculation.     */    static int word0(double d)    {        long dBits = Double.doubleToLongBits(d);        return (int)(dBits >> 32);    }    static double setWord0(double d, int i)    {        long dBits = Double.doubleToLongBits(d);        dBits = ((long)i << 32) | (dBits & 0x0FFFFFFFFL);        return Double.longBitsToDouble(dBits);    }    static int word1(double d)    {        long dBits = Double.doubleToLongBits(d);        return (int)(dBits);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -