📄 floatconv.c
字号:
i = 0; c = Brealloc(c, a->k); c->sign = i; wa = a->wds; xa = a->x; xae = xa + wa; wb = b->wds; xb = b->x; xbe = xb + wb; xc = c->x; borrow = 0; do { y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; borrow = y >> 16; Sign_Extend(borrow, y); z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; borrow = z >> 16; Sign_Extend(borrow, z); Storeinc(xc, z, y); } while(xb < xbe); while(xa < xae) { y = (*xa & 0xffff) + borrow; borrow = y >> 16; Sign_Extend(borrow, y); z = (*xa++ >> 16) + borrow; borrow = z >> 16; Sign_Extend(borrow, z); Storeinc(xc, z, y); } while(!*--xc) wa--; c->wds = wa; return c; }static doubleulp#ifdef KR_headers (x) double x;#else (double x)#endif{ register _G_int32_t L; double a; L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;#ifndef Sudden_Underflow if (L > 0) {#endif#ifdef IBM L |= Exp_msk1 >> 4;#endif setwords(a, L, 0);#ifndef Sudden_Underflow } else { L = -L >> Exp_shift; if (L < Exp_shift) setwords(a, 0x80000 >> L, 0); else { L -= Exp_shift; setwords(a, 0, L >= 31 ? 1 : 1 << (31 - L)); } }#endif return a; }static doubleb2d#ifdef KR_headers (a, e) Bigint *a; int *e;#else (Bigint *a, int *e)#endif{ unsigned32 *xa, *xa0, w, y, z; int k; double d; unsigned32 d0, d1; xa0 = a->x; xa = xa0 + a->wds; y = *--xa;#ifdef DEBUG if (!y) Bug("zero y in b2d");#endif k = hi0bits(y); *e = 32 - k; if (k < Ebits) { d0 = Exp_1 | y >> (Ebits - k); w = xa > xa0 ? *--xa : 0;#ifndef _DOUBLE_IS_32BITS d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);#endif goto ret_d; } z = xa > xa0 ? *--xa : 0; if (k -= Ebits) { d0 = Exp_1 | y << k | z >> (32 - k); y = xa > xa0 ? *--xa : 0;#ifndef _DOUBLE_IS_32BITS d1 = z << k | y >> (32 - k);#endif } else { d0 = Exp_1 | y;#ifndef _DOUBLE_IS_32BITS d1 = z;#endif } ret_d:#ifdef VAX setwords(d, d0 >> 16 | d0 << 16, d1 >> 16 | d1 << 16);#else setwords (d, d0, d1);#endif return d; }static Bigint *d2b#ifdef KR_headers (result, d, e, bits) Bigint *result; double d; _G_int32_t *e, *bits;#else (Bigint *result, double d, _G_int32_t *e, _G_int32_t *bits)#endif{ int de, i, k; unsigned32 *x, y, z; unsigned32 d0, d1;#ifdef VAX d0 = word0(d) >> 16 | word0(d) << 16; d1 = word1(d) >> 16 | word1(d) << 16;#else d0 = word0(d); d1 = word1(d);#endif result = Brealloc(result, 1); x = result->x; z = d0 & Frac_mask; d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ de = (int)(d0 >> Exp_shift); /* The exponent part of d. */ /* Put back the suppressed high-order bit, if normalized. */#ifndef IBM#ifndef Sudden_Underflow if (de)#endif z |= Exp_msk11;#endif#ifndef _DOUBLE_IS_32BITS if ((y = d1)) { if ((k = lo0bits(&y))) { x[0] = y | z << (32 - k); z >>= k; } else x[0] = y; i = result->wds = (x[1] = z) ? 2 : 1; } else {#endif /* !_DOUBLE_IS_32BITS */#ifdef DEBUG if (!z) Bug("Zero passed to d2b");#endif k = lo0bits(&z); x[0] = z; i = result->wds = 1;#ifndef _DOUBLE_IS_32BITS k += 32; }#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; *bits = 32*i - hi0bits(x[i-1]); }#endif return result; }static doubleratio#ifdef KR_headers (a, b) Bigint *a, *b;#else (Bigint *a, Bigint *b)#endif{ double da, db; int k, ka, kb; da = b2d(a, &ka); db = b2d(b, &kb); k = ka - kb + 32*(a->wds - b->wds);#ifdef IBM if (k > 0) { addword0(da, (k >> 2)*Exp_msk1); if (k &= 3) da *= 1 << k; } else { k = -k; addword0(db,(k >> 2)*Exp_msk1); if (k &= 3) db *= 1 << k; }#else if (k > 0) addword0(da, k*Exp_msk1); else { k = -k; addword0(db, k*Exp_msk1); }#endif return da / 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 };#ifdef IEEE_Arithstatic CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };#define n_bigtens 5#else#ifdef IBMstatic CONST double bigtens[] = { 1e16, 1e32, 1e64 };static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };#define n_bigtens 3#else/* Also used for the case when !_DOUBLE_IS_32BITS. */static CONST double bigtens[] = { 1e16, 1e32 };static CONST double tinytens[] = { 1e-16, 1e-32 };#define n_bigtens 2#endif#endif double_IO_strtod#ifdef KR_headers (s00, se) CONST char *s00; char **se;#else (CONST char *s00, char **se)#endif{ _G_int32_t 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; _G_int32_t L; unsigned32 y, z; Bigint _bb, _b_avail, _bd, _bd0, _bs, _delta; Bigint *bb = Binit(&_bb); Bigint *bd = Binit(&_bd); Bigint *bd0 = Binit(&_bd0); Bigint *bs = Binit(&_bs); Bigint *b_avail = Binit(&_b_avail); Bigint *delta = Binit(&_delta); TEST_ENDIANNESS; sign = nz0 = nz = 0; rv = 0.; (void)&rv; /* Force rv into the stack */ for(s = s00;;s++) switch(*s) { case '-': sign = 1; /* no break */ case '+': if (*++s) goto break2; /* no break */ case 0: /* "+" and "-" should be reported as an error? */ sign = 0; s = s00; goto ret; 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; 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) { s = s00; goto ret; } 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') { e = c - '0'; s1 = s; while((c = *++s) >= '0' && c <= '9') e = 10*e + c - '0'; if (s - s1 > 8) /* Avoid confusion from exponents * so large that e might overflow. */ e = 9999999; if (esign) e = -e; } else e = 0; } else s = s00; } if (!nd) { if (!nz && !nz0) s = s00; 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; rv = y; if (k > 9) rv = tens[k - 9] * rv + z; if (nd <= DBL_DIG#ifndef RND_PRODQUOT && FLT_ROUNDS == 1#endif ) { if (!e) goto ret; if (e > 0) { if (e <= Ten_pmax) {#ifdef VAX goto vax_ovfl_check;#else /* rv = */ rounded_product(rv, tens[e]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -