📄 dtoa.cpp
字号:
#ifdef Pack_32 if ((y = d1)) { if ((k = lo0bits(&y))) { x[0] = y | z << 32 - k; z >>= k; } else x[0] = y;#ifndef Sudden_Underflow i =#endif b->wds = (x[1] = z) ? 2 : 1; } else {#ifdef DEBUG if (!z) Bug("Zero passed to d2b");#endif k = lo0bits(&z); x[0] = z;#ifndef Sudden_Underflow i =#endif b->wds = 1; k += 32; }#else if (y = d1) { if (k = lo0bits(&y)) if (k >= 16) { x[0] = y | z << 32 - k & 0xffff; x[1] = z >> k - 16 & 0xffff; x[2] = z >> k; i = 2; } else { x[0] = y & 0xffff; x[1] = y >> 16 | z << 16 - k & 0xffff; x[2] = z >> k & 0xffff; x[3] = z >> k+16; i = 3; } else { x[0] = y & 0xffff; x[1] = y >> 16; x[2] = z & 0xffff; x[3] = z >> 16; i = 3; } } else {#ifdef DEBUG if (!z) Bug("Zero passed to d2b");#endif k = lo0bits(&z); if (k >= 16) { x[0] = z; i = 0; } else { x[0] = z & 0xffff; x[1] = z >> 16; i = 1; } k += 32; } while(!x[i]) --i; b->wds = i + 1;#endif#ifndef Sudden_Underflow if (de) {#endif#ifdef IBM *e = (de - Bias - (P-1) << 2) + k; *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);#else *e = de - Bias - (P-1) + k; *bits = P - k;#endif#ifndef Sudden_Underflow } else { *e = de - Bias - (P-1) + 1 + k;#ifdef Pack_32 *bits = 32*i - hi0bits(x[i-1]);#else *bits = (i+2)*16 - hi0bits(x[i]);#endif }#endif return b; }#undef d0#undef d1 static doubleratio#ifdef KR_headers (a, b) Bigint *a, *b;#else (Bigint *a, Bigint *b)#endif{ double da, db; int k, ka, kb; dval(da) = b2d(a, &ka); dval(db) = b2d(b, &kb);#ifdef Pack_32 k = ka - kb + 32*(a->wds - b->wds);#else k = ka - kb + 16*(a->wds - b->wds);#endif#ifdef IBM if (k > 0) { word0(da) += (k >> 2)*Exp_msk1; if (k &= 3) dval(da) *= 1 << k; } else { k = -k; word0(db) += (k >> 2)*Exp_msk1; if (k &= 3) dval(db) *= 1 << k; }#else if (k > 0) word0(da) += k*Exp_msk1; else { k = -k; word0(db) += k*Exp_msk1; }#endif return dval(da) / dval(db); } static CONST doubletens[] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22#ifdef VAX , 1e23, 1e24#endif }; static CONST double#ifdef IEEE_Arithbigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,#ifdef Avoid_Underflow 9007199254740992.*9007199254740992.e-256 /* = 2^106 * 1e-53 */#else 1e-256#endif };/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow *//* flag unnecessarily. It leads to a song and dance at the end of strtod. */#define Scale_Bit 0x10#define n_bigtens 5#else#ifdef IBMbigtens[] = { 1e16, 1e32, 1e64 };static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };#define n_bigtens 3#elsebigtens[] = { 1e16, 1e32 };static CONST double tinytens[] = { 1e-16, 1e-32 };#define n_bigtens 2#endif#endif#ifndef IEEE_Arith#undef INFNAN_CHECK#endif#ifdef INFNAN_CHECK#ifndef NAN_WORD0#define NAN_WORD0 0x7ff80000#endif#ifndef NAN_WORD1#define NAN_WORD1 0#endif static intmatch#ifdef KR_headers (sp, t) char **sp, *t;#else (CONST char **sp, CONST char *t)#endif{ int c, d; CONST char *s = *sp; while((d = *t++)) { if ((c = *++s) >= 'A' && c <= 'Z') c += 'a' - 'A'; if (c != d) return 0; } *sp = s + 1; return 1; }#ifndef No_Hex_NaN static voidhexnan#ifdef KR_headers (rvp, sp) double *rvp; CONST char **sp;#else (double *rvp, CONST char **sp)#endif{ ULong c, x[2]; CONST char *s; int havedig, udx0, xshift; x[0] = x[1] = 0; havedig = xshift = 0; udx0 = 1; s = *sp; while((c = *(CONST unsigned char*)++s)) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'a' && c <= 'f') c += 10 - 'a'; else if (c >= 'A' && c <= 'F') c += 10 - 'A'; else if (c <= ' ') { if (udx0 && havedig) { udx0 = 0; xshift = 1; } continue; } else if (/*(*/ c == ')' && havedig) { *sp = s + 1; break; } else return; /* invalid form: don't change *sp */ havedig = 1; if (xshift) { xshift = 0; x[0] = x[1]; x[1] = 0; } if (udx0) x[0] = (x[0] << 4) | (x[1] >> 28); x[1] = (x[1] << 4) | c; } if ((x[0] &= 0xfffff) || x[1]) { word0(*rvp) = Exp_mask | x[0]; word1(*rvp) = x[1]; } }#endif /*No_Hex_NaN*/#endif /* INFNAN_CHECK */ doublestrtod#ifdef KR_headers (s00, se) CONST char *s00; char **se;#else (CONST char *s00, char **se)#endif{#ifdef Avoid_Underflow int scale;#endif int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; double aadj, aadj1, adj, rv, rv0; Long L; ULong y, z; Bigint *bb = NULL, *bb1 = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL;#ifdef SET_INEXACT int inexact, oldinexact;#endif#ifdef Honor_FLT_ROUNDS int rounding;#endif#ifdef USE_LOCALE CONST char *s2;#endif sign = nz0 = nz = 0; dval(rv) = 0.; for(s = s00;;s++) switch(*s) { case '-': sign = 1; /* no break */ case '+': if (*++s) goto break2; /* no break */ case 0: goto ret0; case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': continue; default: goto break2; } break2: if (*s == '0') { nz0 = 1; while(*++s == '0') ; if (!*s) goto ret; } s0 = s; y = z = 0; for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) if (nd < 9) y = 10*y + c - '0'; else if (nd < 16) z = 10*z + c - '0'; nd0 = nd;#ifdef USE_LOCALE s1 = localeconv()->decimal_point; if (c == *s1) { c = '.'; if (*++s1) { s2 = s; for(;;) { if (*++s2 != *s1) { c = 0; break; } if (!*++s1) { s = s2; break; } } } }#endif if (c == '.') { c = *++s; if (!nd) { for(; c == '0'; c = *++s) nz++; if (c > '0' && c <= '9') { s0 = s; nf += nz; nz = 0; goto have_dig; } goto dig_done; } for(; c >= '0' && c <= '9'; c = *++s) { have_dig: nz++; if (c -= '0') { nf += nz; for(i = 1; i < nz; i++) if (nd++ < 9) y *= 10; else if (nd <= DBL_DIG + 1) z *= 10; if (nd++ < 9) y = 10*y + c; else if (nd <= DBL_DIG + 1) z = 10*z + c; nz = 0; } } } dig_done: e = 0; if (c == 'e' || c == 'E') { if (!nd && !nz && !nz0) { goto ret0; } s00 = s; esign = 0; switch(c = *++s) { case '-': esign = 1; case '+': c = *++s; } if (c >= '0' && c <= '9') { while(c == '0') c = *++s; if (c > '0' && c <= '9') { L = c - '0'; s1 = s; while((c = *++s) >= '0' && c <= '9') L = 10*L + c - '0'; if (s - s1 > 8 || L > 19999) /* Avoid confusion from exponents * so large that e might overflow. */ e = 19999; /* safe for 16 bit ints */ else e = (int)L; if (esign) e = -e; } else e = 0; } else s = s00; } if (!nd) { if (!nz && !nz0) {#ifdef INFNAN_CHECK /* Check for Nan and Infinity */ switch(c) { case 'i': case 'I': if (match(&s,"nf")) { --s; if (!match(&s,"inity")) ++s; word0(rv) = 0x7ff00000; word1(rv) = 0; goto ret; } break; case 'n': case 'N': if (match(&s, "an")) { word0(rv) = NAN_WORD0; word1(rv) = NAN_WORD1;#ifndef No_Hex_NaN if (*s == '(') /*)*/ hexnan(&rv, &s);#endif goto ret; } }#endif /* INFNAN_CHECK */ ret0: s = s00; sign = 0; } goto ret; } e1 = e -= nf; /* Now we have nd0 digits, starting at s0, followed by a * decimal point, followed by nd-nd0 digits. The number we're * after is the integer represented by those digits times * 10**e */ if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; dval(rv) = y; if (k > 9) {#ifdef SET_INEXACT if (k > DBL_DIG) oldinexact = get_inexact();#endif dval(rv) = tens[k - 9] * dval(rv) + z; } bd0 = 0; if (nd <= DBL_DIG#ifndef RND_PRODQUOT#ifndef Honor_FLT_ROUNDS && Flt_Rounds == 1#endif#endif ) { if (!e) goto ret; if (e > 0) { if (e <= Ten_pmax) {#ifdef VAX goto vax_ovfl_check;#else#ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { rv = -rv; sign = 0; }#endif /* rv = */ rounded_product(dval(rv), tens[e]); goto ret;#endif } i = DBL_DIG - nd; if (e <= Ten_pmax + i) { /* A fancier test would sometimes let us do * this for larger i values. */#ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { rv = -rv; sign = 0; }#endif e -= i; dval(rv) *= tens[i];#ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here... */ vax_ovfl_check: word0(rv) -= P*Exp_msk1; /* rv = */ rounded_product(dval(rv), tens[e]); if ((word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto ovfl; word0(rv) += P*Exp_msk1;#else /* rv = */ rounded_product(dval(rv), tens[e]);#endif goto ret; } }#ifndef Inaccurate_Divide else if (e >= -Ten_pmax) {#ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { rv = -rv; sign = 0; }#endif /* rv = */ rounded_quotient(dval(rv), tens[-e]); goto ret; }#endif } e1 += nd - k;#ifdef IEEE_Arith#ifdef SET_INEXACT inexact = 1; if (k <= DBL_DIG) oldinexact = get_inexact();#endif#ifdef Avoid_Underflow scale = 0;#endif#ifdef Honor_FLT_ROUNDS if ((rounding = Flt_Rounds) >= 2) { if (sign) rounding = rounding == 2 ? 0 : 2; else if (rounding != 2) rounding = 0; }#endif#endif /*IEEE_Arith*/ /* Get starting approximation = rv * 10**e1 */ if (e1 > 0) { if ((i = e1 & 15)) dval(rv) *= tens[i]; if (e1 &= ~15) { if (e1 > DBL_MAX_10_EXP) { ovfl:#ifndef NO_ERRNO errno = ERANGE;#endif /* Can't trust HUGE_VAL */#ifdef IEEE_Arith#ifdef Honor_FLT_ROUNDS switch(rounding) { case 0: /* toward 0 */ case 3: /* toward -infinity */ word0(rv) = Big0; word1(rv) = Big1; break; default: word0(rv) = Exp_mask; word1(rv) = 0; }#else /*Honor_FLT_ROUNDS*/ word0(rv) = Exp_mask; word1(rv) = 0;#endif /*Honor_FLT_ROUNDS*/#ifdef SET_INEXACT /* set overflow bit */ dval(rv0) = 1e300; dval(rv0) *= dval(rv0);#endif#else /*IEEE_Arith*/ word0(rv) = Big0; word1(rv) = Big1;#endif /*IEEE_Arith*/ if (bd0) goto retfree; goto ret; } e1 >>= 4; for(j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) dval(rv) *= bigtens[j]; /* The last multiplication could overflow. */ word0(rv) -= P*Exp_msk1; dval(rv) *= bigtens[j]; if ((z = word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P)) goto ovfl; if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { /* set to largest number */ /* (Can't trust DBL_MAX) */ word0(rv) = Big0; word1(rv) = Big1; } else word0(rv) += P*Exp_msk1; } } else if (e1 < 0) { e1 = -e1; if ((i = e1 & 15)) dval(rv) /= tens[i]; if (e1 >>= 4) { if (e1 >= 1 << n_bigtens) goto undfl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -