📄 double_decim.c
字号:
} /* Divide x up into integer part ix and fraction part fx. */ ix = *px; fx = ix; if (ix.exponent <= -1) {/* All fraction. */ ix.fpclass = fp_zero; } else if (ix.exponent >= 159) { /* All integer. */ fx.fpclass = fp_zero; } else if ((ix.exponent % 32) == 31) { /* Integer/fraction boundary * is conveniently on a word * boundary. */ imask = (ix.exponent + 1) / 32; /* Words 0..imask-1 are * integer; imask..SIZE are * fraction. */ for (i = 0; i < imask; i++) fx.significand[i] = 0; for (; i < UNPACKED_SIZE; i++) ix.significand[i] = 0; _fp_normalize(&fx); } else { /* Integer/fraction boundary falls in the * middle of a word. */ imask = (ix.exponent + 1) / 32; /* Words 0..imask-1 are * integer; imask is integer * and fraction ; * imask+1..SIZE are * fraction. */ for (i = 0; i < imask; i++) fx.significand[i] = 0; fmask = (1 << (31 - (ix.exponent % 32))) - 1; fx.significand[imask] &= fmask; ix.significand[imask] &= ~fmask; for (i = (imask + 1); i < UNPACKED_SIZE; i++) ix.significand[i] = 0; _fp_normalize(&fx); } if (ix.fpclass != fp_zero) { /* Compute integer part of result. */ if (pm->df == floating_form) nsig = pm->ndigits + 1; /* Significant digits wanted * for E format, plus one for * rounding. */ else nsig = _INTEGER_SIZE; /* Significant digits wanted * for F format == all. */ binary_to_decimal_integer(&ix, nsig, is, &intzeros, &intsigs); } else { intsigs = 0; intzeros = 0; } intdigs = intsigs + intzeros; fracdigs = 0; if (((pm->df == fixed_form) && (pm->ndigits >= 0)) || ((pm->df == floating_form) && ((pm->ndigits + 1) > intdigs))) { /* Need to compute * fraction part. */ if (pm->df == floating_form) { /* Need more significant * digits. */ nsig = pm->ndigits + 2 - intdigs; /* Add two for rounding, * sticky. */ if (nsig > DECIMAL_STRING_LENGTH) nsig = DECIMAL_STRING_LENGTH; nfrac = 1; } else { /* Need fraction digits. */ nsig = 0; nfrac = pm->ndigits + 2; /* Add two for rounding, * sticky. */ if (nfrac > DECIMAL_STRING_LENGTH) nfrac = DECIMAL_STRING_LENGTH; } binary_to_decimal_fraction(&fx, nsig, nfrac, fs, &fraczeros, &fracsigs); fracdigs = fraczeros + fracsigs; } if (pm->df == floating_form) { /* Combine integer and fraction for E * format. */ idsbound = intsigs; if (idsbound > pm->ndigits) idsbound = pm->ndigits; for (ids = 0; ids < idsbound; ids++) pd->ds[ids] = is[ids]; /* Put integer into output string. */ idsbound = intsigs + intzeros; if (idsbound > pm->ndigits) idsbound = pm->ndigits; for (; ids < idsbound; ids++) pd->ds[ids] = '0'; if (ids == pm->ndigits) { /* Integer part had enough * significant digits. */ pd->ndigits = ids; pd->exponent = intdigs - ids; if (ids < intdigs) { /* Gather rounding info. */ if (ids < intsigs) round = is[ids++]; else round = '0'; for (; (is[ids] == '0') && (ids < intsigs); ids++); if (ids < intsigs) sticky = 1; if (fx.fpclass != fp_zero) sticky = 1; } else {/* Integer part is exact - round from * fraction. */ if (fx.fpclass != fp_zero) { int stickystart; /* Fraction non-zero. */ if (fraczeros > 0) { /* Round digit is zero. */ round = '0'; stickystart = 0; /* Stickies start with * fs[0]. */ } else { /* Round digit is fs[0]. */ round = fs[0]; stickystart = 1; /* Stickies start with * fs[1]. */ } if (sticky == 0) { /* Search for sticky * bits. */ for (ids = stickystart; (fs[ids] == '0') && (ids < fracdigs); ids++); if (ids < fracdigs) sticky = 1; } } } } else { /* Need more significant digits from fraction * part. */ idsbound = pm->ndigits - ids; if (ids == 0) { /* No integer part - find first * significant digit. */ for (i = 0; fs[i] == '0'; i++); idsbound = i + idsbound + fraczeros; i += fraczeros; /* Point i at first * significant digit. */ } else i = 0; if (idsbound > fracdigs) idsbound = fracdigs; pd->exponent = -idsbound; if (fraczeros < idsbound) /* Compute number of * leading zeros * required. */ lzbound = fraczeros; else lzbound = idsbound; for (; (i < lzbound); i++) pd->ds[ids++] = '0'; for (; (i < idsbound); i++) pd->ds[ids++] = fs[i - fraczeros]; i -= fraczeros; /* Don't worry about leading zeros * from now on, we're just rounding */ if (i < fracsigs) { /* Gather rounding info. */ if (i < 0) round = '0'; else round = fs[i]; i++; if (sticky == 0) { /* Find out if remainder * is exact. */ if (i < 0) i = 0; for (; (fs[i] == '0') && (i < fracsigs); i++); if (i < fracsigs) sticky = 1; } } else {/* Fraction part is exact - add zero digits * if required. */ for (; ids < pm->ndigits; ids++) pd->ds[ids] = '0'; } pd->ndigits = ids; } decimal_round(pm, pd, ps, round, sticky); } else { /* Combine integer and fraction for F format. */ if (pm->ndigits >= 0) { /* Normal F format. */ if ((intdigs + pm->ndigits) >= DECIMAL_STRING_LENGTH) goto overflow; for (ids = 0; ids < intsigs; ids++) pd->ds[ids] = is[ids]; for (; ids < intdigs; ids++) pd->ds[ids] = '0'; /* Copy integer digits. */ idsbound = fracdigs; if (idsbound > pm->ndigits) idsbound = pm->ndigits; if (fraczeros < idsbound) /* Compute number of * leading zeros * required. */ lzbound = fraczeros; else lzbound = idsbound; for (i = 0; (i < lzbound); i++) pd->ds[ids++] = '0'; for (; (i < idsbound); i++) pd->ds[ids++] = fs[i - fraczeros]; /* Copy fraction digits. */ for (; i < pm->ndigits; i++) pd->ds[ids++] = '0'; /* Copy trailing zeros if necessary. */ pd->ndigits = ids; pd->exponent = intdigs - ids; i -= fraczeros; /* Don't worry about leading zeros * from now on, we're just rounding */ if (i < fracsigs) { /* Gather rounding info. */ if (i < 0) round = '0'; else round = fs[i]; i++; if (sticky == 0) { /* Find out if remainder * is exact. */ if (i < 0) i = 0; for (; (fs[i] == '0') && (i < fracsigs); i++); if (i < fracsigs) sticky = 1; } } decimal_round(pm, pd, ps, round, sticky); } else { /* Bizarre F format - round to left of point. */ int roundpos = -pm->ndigits; if (intdigs >= DECIMAL_STRING_LENGTH) goto overflow; if (roundpos >= DECIMAL_STRING_LENGTH) goto overflow; if (intdigs <= roundpos) { /* Not enough integer * digits. */ if (intdigs == roundpos) { round = is[0]; i = 1; } else { round = '0'; i = 0; } for (; (is[i] == '0') && (i < intsigs); i++); /* Search for sticky bits. */ if (i < intsigs) sticky = 1; pd->ndigits = 0; } else {/* Some integer digits do not get rounded * away. */#ifdef _NO_GOOD for (ids = 0; ids < (intsigs - roundpos); ids++) pd->ds[ids] = is[ids]; for (ids = 0; ids < (intdigs - roundpos); ids++) pd->ds[ids] = '0';#else { int ncopy = intsigs - roundpos; if (ncopy > 0) { /* Copy integer digits. */ (void) memcpy(&(pd->ds[0]), &(is[0]), ncopy); ids = ncopy; } } { int ncopy = intdigs - roundpos - ids ; if (ncopy > 0) { (void) memset(&(pd->ds[ids]), '0', ncopy); ids += ncopy; } }#endif /* _NO_GOOD */ /* Copy integer digits. */ pd->ndigits = ids; if (ids < intsigs) { /* Inexact. */ round = is[ids++]; for (; (is[ids] == '0') && (ids < intsigs); ids++); /* Search for non-zero digits. */ if (ids < intsigs) sticky = 1; } } if (fx.fpclass != fp_zero) sticky = 1; decimal_round(pm, pd, ps, round, sticky); for (i = pd->ndigits; i < (pd->ndigits + roundpos); i++) pd->ds[i] = '0'; /* Blank out rounded * away digits. */ pd->exponent = 0; pd->ndigits = i; pd->ds[i] = 0; /* Terminate string. */ } }}voiddouble_to_decimal(px, pm, pd, ps) double *px; decimal_mode *pm; decimal_record *pd; fp_exception_field_type *ps;{ double_equivalence kluge; unpacked u; *ps = 0; /* Initialize *ps. */ kluge.x = *px; pd->sign = kluge.f.msw.sign; pd->fpclass = _class_double(px); switch (pd->fpclass) { case fp_zero: break; case fp_infinity: break; case fp_quiet: break; case fp_signaling: break; default: _unpack_double(&u, &kluge.x); _unpacked_to_decimal(&u, pm, pd, ps); }}voidquadruple_to_decimal(px, pm, pd, ps) quadruple *px; decimal_mode *pm; decimal_record *pd; fp_exception_field_type *ps;{ quadruple_equivalence kluge; unpacked u; int i; *ps = 0; /* Initialize *ps - no exceptions. */ for (i = 0; i < 4; i++) kluge.x.u[i] = px->u[i]; pd->sign = kluge.f.msw.sign; pd->fpclass = _class_quadruple(px); switch (pd->fpclass) { case fp_zero: break; case fp_infinity: break; case fp_quiet: break; case fp_signaling: break; default: _unpack_quadruple(&u, px); _unpacked_to_decimal(&u, pm, pd, ps); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -