📄 dtoa.java
字号:
} leftright = true; ilim = ilim1 = 0; switch(mode) { case 0: case 1: ilim = ilim1 = -1; i = 18; ndigits = 0; break; case 2: leftright = false; /* no break */ case 4: if (ndigits <= 0) ndigits = 1; ilim = ilim1 = i = ndigits; break; case 3: leftright = false; /* no break */ case 5: i = ndigits + k + 1; ilim = i; ilim1 = i - 1; if (i <= 0) i = 1; } /* ilim is the maximum number of significant digits we want, based on k and ndigits. */ /* ilim1 is the maximum number of significant digits we want, based on k and ndigits, when it turns out that k was computed too high by one. */ boolean fast_failed = false; if (ilim >= 0 && ilim <= Quick_max && try_quick) { /* Try to get by with floating-point arithmetic. */ i = 0; d2 = d; k0 = k; ilim0 = ilim; ieps = 2; /* conservative */ /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */ if (k > 0) { ds = tens[k&0xf]; j = k >> 4; if ((j & Bletch) != 0) { /* prevent overflows */ j &= Bletch - 1; d /= bigtens[n_bigtens-1]; ieps++; } for(; (j != 0); j >>= 1, i++) if ((j & 1) != 0) { ieps++; ds *= bigtens[i]; } d /= ds; } else if ((j1 = -k) != 0) { d *= tens[j1 & 0xf]; for(j = j1 >> 4; (j != 0); j >>= 1, i++) if ((j & 1) != 0) { ieps++; d *= bigtens[i]; } } /* Check that k was computed correctly. */ if (k_check && d < 1.0 && ilim > 0) { if (ilim1 <= 0) fast_failed = true; else { ilim = ilim1; k--; d *= 10.; ieps++; } } /* eps bounds the cumulative error. */// eps = ieps*d + 7.0;// word0(eps) -= (P-1)*Exp_msk1; eps = ieps*d + 7.0; eps = setWord0(eps, word0(eps) - (P-1)*Exp_msk1); if (ilim == 0) { S = mhi = null; d -= 5.0; if (d > eps) { buf.append('1'); k++; return k + 1; } if (d < -eps) { buf.setLength(0); buf.append('0'); /* copy "0" to buffer */ return 1; } fast_failed = true; } if (!fast_failed) { fast_failed = true; if (leftright) { /* Use Steele & White method of only * generating digits needed. */ eps = 0.5/tens[ilim-1] - eps; for(i = 0;;) { L = (long)d; d -= L; buf.append((char)('0' + L)); if (d < eps) { return k + 1; } if (1.0 - d < eps) {// goto bump_up; char lastCh; while (true) { lastCh = buf.charAt(buf.length() - 1); buf.setLength(buf.length() - 1); if (lastCh != '9') break; if (buf.length() == 0) { k++; lastCh = '0'; break; } } buf.append((char)(lastCh + 1)); return k + 1; } if (++i >= ilim) break; eps *= 10.0; d *= 10.0; } } else { /* Generate ilim digits, then fix them up. */ eps *= tens[ilim-1]; for(i = 1;; i++, d *= 10.0) { L = (long)d; d -= L; buf.append((char)('0' + L)); if (i == ilim) { if (d > 0.5 + eps) {// goto bump_up; char lastCh; while (true) { lastCh = buf.charAt(buf.length() - 1); buf.setLength(buf.length() - 1); if (lastCh != '9') break; if (buf.length() == 0) { k++; lastCh = '0'; break; } } buf.append((char)(lastCh + 1)); return k + 1; } else if (d < 0.5 - eps) { stripTrailingZeroes(buf); // while(*--s == '0') ;// s++; return k + 1; } break; } } } } if (fast_failed) { buf.setLength(0); d = d2; k = k0; ilim = ilim0; } } /* Do we have a "small" integer? */ if (be[0] >= 0 && k <= Int_max) { /* Yes. */ ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = null; if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds)) { buf.setLength(0); buf.append('0'); /* copy "0" to buffer */ return 1; } buf.append('1'); k++; return k + 1; } for(i = 1;; i++) { L = (long) (d / ds); d -= L*ds; buf.append((char)('0' + L)); if (i == ilim) { d += d; if ((d > ds) || (d == ds && (((L & 1) != 0) || biasUp))) {// bump_up:// while(*--s == '9')// if (s == buf) {// k++;// *s = '0';// break;// }// ++*s++; char lastCh; while (true) { lastCh = buf.charAt(buf.length() - 1); buf.setLength(buf.length() - 1); if (lastCh != '9') break; if (buf.length() == 0) { k++; lastCh = '0'; break; } } buf.append((char)(lastCh + 1)); } break; } d *= 10.0; if (d == 0) break; } return k + 1; } m2 = b2; m5 = b5; mhi = mlo = null; if (leftright) { if (mode < 2) { i = (denorm) ? be[0] + (Bias + (P-1) - 1 + 1) : 1 + P - bbits[0]; /* i is 1 plus the number of trailing zero bits in d's significand. Thus, (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */ } else { j = ilim - 1; if (m5 >= j) m5 -= j; else { s5 += j -= m5; b5 += j; m5 = 0; } if ((i = ilim) < 0) { m2 -= i; i = 0; } /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */ } b2 += i; s2 += i; mhi = BigInteger.valueOf(1); /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or input (when mode < 2) significant digit, divided by 10^k. */ } /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in b2, m2, and s2 without changing the equalities. */ if (m2 > 0 && s2 > 0) { i = (m2 < s2) ? m2 : s2; b2 -= i; m2 -= i; s2 -= i; } /* Fold b5 into b and m5 into mhi. */ if (b5 > 0) { if (leftright) { if (m5 > 0) { mhi = pow5mult(mhi, m5); b1 = mhi.multiply(b); b = b1; } if ((j = b5 - m5) != 0) b = pow5mult(b, j); } else b = pow5mult(b, b5); } /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */ S = BigInteger.valueOf(1); if (s5 > 0) S = pow5mult(S, s5); /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */ /* Check for special case that d is a normalized power of 2. */ spec_case = false; if (mode < 2) { if ( (word1(d) == 0) && ((word0(d) & Bndry_mask) == 0) && ((word0(d) & (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 decimal output string's value is less than d. */ b2 += Log2P; s2 += Log2P; spec_case = true; } } /* Arrange for convenient computation of quotients: * shift left if necessary so divisor has 4 leading 0 bits. * * Perhaps we should just compute leading 28 bits of S once * and for all and pass them and a shift to quorem, so it * can do shifts and ors to compute the numerator for q. */ byte [] S_bytes = S.toByteArray(); int S_hiWord = 0; for (int idx = 0; idx < 4; idx++) { S_hiWord = (S_hiWord << 8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -