📄 dtoa.java
字号:
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); } /* Return b * 5^k. k must be nonnegative. */ // XXXX the C version built a cache of these static BigInteger pow5mult(BigInteger b, int k) { return b.multiply(BigInteger.valueOf(5).pow(k)); } static boolean roundOff(StringBuffer buf) { int i = buf.length(); while (i != 0) { --i; char c = buf.charAt(i); if (c != '9') { buf.setCharAt(i, (char)(c + 1)); buf.setLength(i + 1); return false; } } buf.setLength(0); return true; } /* Always emits at least one digit. */ /* If biasUp is set, then rounding in modes 2 and 3 will round away from zero * when the number is exactly halfway between two representable values. For example, * rounding 2.5 to zero digits after the decimal point will return 3 and not 2. * 2.49 will still round to 2, and 2.51 will still round to 3. */ /* bufsize should be at least 20 for modes 0 and 1. For the other modes, * bufsize should be two greater than the maximum number of output characters expected. */ static int JS_dtoa(double d, int mode, boolean biasUp, int ndigits, boolean[] sign, StringBuffer buf) { /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; trailing zeros are suppressed from the returned string. If not null, *rve is set to point to the end of the return value. If d is +-Infinity or NaN, then *decpt is set to 9999. mode: 0 ==> shortest string that yields d when read in and rounded to nearest. 1 ==> like 0, but with Steele & White stopping rule; e.g. with IEEE P754 arithmetic , mode 0 gives 1e23 whereas mode 1 gives 9.999999999999999e22. 2 ==> max(1,ndigits) significant digits. This gives a return value similar to that of ecvt, except that trailing zeros are suppressed. 3 ==> through ndigits past the decimal point. This gives a return value similar to that from fcvt, except that trailing zeros are suppressed, and ndigits can be negative. 4-9 should give the same return values as 2-3, i.e., 4 <= mode <= 9 ==> same return as mode 2 + (mode & 1). These modes are mainly for debugging; often they run slower but sometimes faster than modes 2-3. 4,5,8,9 ==> left-to-right digit generation. 6-9 ==> don't try fast floating-point estimate (if applicable). Values of mode other than 0-9 are treated as mode 0. Sufficient space is allocated to the return value to hold the suppressed trailing zeros. */ int b2, b5, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0, m2, m5, s2, s5; char dig; long L; long x; BigInteger b, b1, delta, mlo, mhi, S; int[] be = new int[1]; int[] bbits = new int[1]; double d2, ds, eps; boolean spec_case, denorm, k_check, try_quick, leftright; if ((word0(d) & Sign_bit) != 0) { /* set sign for everything, including 0's and NaNs */ sign[0] = true; // word0(d) &= ~Sign_bit; /* clear sign bit */ d = setWord0(d, word0(d) & ~Sign_bit); } else sign[0] = false; if ((word0(d) & Exp_mask) == Exp_mask) { /* Infinity or NaN */ buf.append(((word1(d) == 0) && ((word0(d) & Frac_mask) == 0)) ? "Infinity" : "NaN"); return 9999; } if (d == 0) {// no_digits: buf.setLength(0); buf.append('0'); /* copy "0" to buffer */ return 1; } b = d2b(d, be, bbits); if ((i = (int)(word0(d) >>> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { d2 = setWord0(d, (word0(d) & Frac_mask1) | Exp_11); /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) * * This suggests computing an approximation k to log10(d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); * * We want k to be too large rather than too small. * The error in the first-order Taylor series approximation * is in our favor, so we just round up the constant enough * to compensate for any error in the multiplication of * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, * adding 1e-13 to the constant term more than suffices. * Hence we adjust the constant term to 0.1760912590558. * (We could get a more accurate k by invoking log10, * but this is probably not worthwhile.) */ i -= Bias; denorm = false; } else { /* d is denormalized */ i = bbits[0] + be[0] + (Bias + (P-1) - 1); x = (i > 32) ? word0(d) << (64 - i) | word1(d) >>> (i - 32) : word1(d) << (32 - i);// d2 = x;// word0(d2) -= 31*Exp_msk1; /* adjust exponent */ d2 = setWord0(x, word0(x) - 31*Exp_msk1); i -= (Bias + (P-1) - 1) + 1; denorm = true; } /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; k = (int)ds; if (ds < 0.0 && ds != k) k--; /* want k = floor(ds) */ k_check = true; if (k >= 0 && k <= Ten_pmax) { if (d < tens[k]) k--; k_check = false; } /* At this point floor(log10(d)) <= k <= floor(log10(d))+1. If k_check is zero, we're guaranteed that k = floor(log10(d)). */ j = bbits[0] - i - 1; /* At this point d = b/2^j, where b is an odd integer. */ if (j >= 0) { b2 = 0; s2 = j; } else { b2 = -j; s2 = 0; } if (k >= 0) { b5 = 0; s5 = k; s2 += k; } else { b2 -= k; b5 = -k; s5 = 0; } /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer, b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */ if (mode < 0 || mode > 9) mode = 0; try_quick = true; if (mode > 5) { mode -= 4; try_quick = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -