?? dtoa.java
字號:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1997-1999 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * Waldemar Horwat * Roger Lawrence * * Alternatively, the contents of this file may be used under the * terms of the GNU Public License (the "GPL"), in which case the * provisions of the GPL are applicable instead of those above. * If you wish to allow use of your version of this file only * under the terms of the GPL and not to allow others to use your * version of this file under the NPL, indicate your decision by * deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete * the provisions above, a recipient may use your version of this * file under either the NPL or the GPL. *//**************************************************************** * * The author of this software is David M. Gay. * * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. * * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. * ***************************************************************/package org.mozilla.javascript;import java.math.BigInteger;class DToA {/* "-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);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -