📄 printf_fp.c
字号:
put ('0'); put ('0'); } } else { cutoff = -prec; roundup = 0; if (e > p) { /* The exponent is bigger than the number of fractional digits. */ MPN_ZERO (r, (e - p) / BITS_PER_MP_LIMB); if ((e - p) % BITS_PER_MP_LIMB == 0) { MPN_COPY (r + (e - p) / BITS_PER_MP_LIMB, f, fsize); rsize = fsize + (e - p) / BITS_PER_MP_LIMB; assert (rsize != 0); } else { assert (fsize != 0); cy = __mpn_lshift (r + (e - p) / BITS_PER_MP_LIMB, f, fsize, (e - p) % BITS_PER_MP_LIMB); rsize = fsize + (e - p) / BITS_PER_MP_LIMB; if (cy) r[rsize++] = cy; } MPN_POW2 (scale, 0); assert (scalesize != 0); /* The number is (E - P) factors of two larger than the fraction can represent; this is the potential error. */ MPN_POW2 (loerr, e - p); assert (loerrsize != 0); } else { /* The number of fractional digits is greater than the exponent. Scale by the difference factors of two. */ MPN_ASSIGN (r, f); MPN_POW2 (scale, p - e); MPN_POW2 (loerr, 0); } MPN_ASSIGN (hierr, loerr); /* Fixup. */ MPN_POW2 (tmp, p - 1); if (MPN_EQ (f, tmp)) { /* Account for unequal gaps. */ assert (hierrsize != 0); cy = __mpn_lshift (hierr, hierr, hierrsize, 1); if (cy) hierr[hierrsize++] = cy; assert (rsize != 0); cy = __mpn_lshift (r, r, rsize, 1); if (cy) r[rsize++] = cy; assert (scalesize != 0); cy = __mpn_lshift (scale, scale, scalesize, 1); if (cy) scale[scalesize++] = cy; } /* scale10 = ceil (scale / 10.0). */ if (__mpn_divmod_1 (scale10, scale, scalesize, 10) != 0) { /* We got a remainder. __mpn_divmod_1 has floor'ed the quotient but we want it to be ceil'ed. Adjust. */ cy = __mpn_add_1 (scale10, scale10, scalesize, 1); if (cy) abort (); } scale10size = scalesize; scale10size -= scale10[scale10size - 1] == 0; k = 0; while (MPN_LT (r, scale10)) { mp_limb cy; --k; cy = __mpn_mul_1 (r, r, rsize, 10); if (cy != 0) r[rsize++] = cy; cy = __mpn_mul_1 (loerr, loerr, loerrsize, 10); if (cy != 0) loerr[loerrsize++] = cy; cy = __mpn_mul_1 (hierr, hierr, hierrsize, 10); if (cy != 0) hierr[hierrsize++] = cy; } do { mp_limb cy; assert (rsize != 0); cy = __mpn_lshift (r2, r, rsize, 1); r2size = rsize; if (cy != 0) r2[r2size++] = cy; /* tmp = r2 + hierr; */ if (r2size > hierrsize) { cy = __mpn_add (tmp, r2, r2size, hierr, hierrsize); tmpsize = r2size; } else { cy = __mpn_add (tmp, hierr, hierrsize, r2, r2size); tmpsize = hierrsize; } if (cy != 0) tmp[tmpsize++] = cy; /* while (r2 + hierr >= 2 * scale) */ assert (scalesize != 0); cy = __mpn_lshift (scale2, scale, scalesize, 1); scale2size = scalesize; if (cy) scale2[scale2size++] = cy; while (MPN_GE (tmp, scale2)) { cy = __mpn_mul_1 (scale, scale, scalesize, 10); if (cy) scale[scalesize++] = cy; ++k; assert (scalesize != 0); cy = __mpn_lshift (scale2, scale, scalesize, 1); scale2size = scalesize; if (cy) scale2[scale2size++] = cy; } /* Perform any necessary adjustment of loerr and hierr to take into account the formatting requirements. */ if (type == 'e') cutoff += k - 1; /* CutOffMode == "relative". */ /* Otherwise CutOffMode == "absolute". */ { /* CutOffAdjust. */ int a = cutoff - k; MPN_VAR (y); MPN_ASSIGN (y, scale); /* There is probably a better way to do this. */ while (a > 0) { cy = __mpn_mul_1 (y, y, ysize, 10); if (cy) y[ysize++] = cy; --a; } while (a < 0) { if (__mpn_divmod_1 (y, y, ysize, 10) != 0) { /* We got a remainder. __mpn_divmod_1 has floor'ed the quotient but we want it to be ceil'ed. Adjust. */ cy = __mpn_add_1 (y, y, ysize, 1); if (cy) abort (); } ysize -= y[ysize - 1] == 0; ++a; } if (MPN_GT (y, loerr)) MPN_ASSIGN (loerr, y); if (MPN_GE (y, hierr)) { MPN_ASSIGN (hierr, y); roundup = 1; /* Recalculate: tmp = r2 + hierr */ if (r2size > hierrsize) { cy = __mpn_add (tmp, r2, r2size, hierr, hierrsize); tmpsize = r2size; } else { cy = __mpn_add (tmp, hierr, hierrsize, r2, r2size); tmpsize = hierrsize; } if (cy != 0) tmp[tmpsize++] = cy; } } /* End CutOffAdjust. */ } while (MPN_GE (tmp, scale2)); /* End Fixup. */ /* First digit. */ hack_digit (); if (type == 'e') { /* Exponential notation. */ int expt = k; /* Base-10 exponent. */ int expt_neg; expt_neg = k < 0; if (expt_neg) expt = - expt; /* Find the magnitude of the exponent. */ j = 10; while (j <= expt) j *= 10; /* Write the first digit. */ put (digit); if (low || high || k == cutoff) { if ((tolower (info->spec) != 'g' && prec > 0) || info->alt) put (*decimal); } else { int stop; put (*decimal); /* Remaining digits. */ do { stop = hack_digit (); put (digit); } while (! stop); } if (tolower (info->spec) != 'g' || info->alt) /* Pad with zeros. */ while (--k >= cutoff) put ('0'); /* Write the exponent. */ put (isupper (info->spec) ? 'E' : 'e'); put (expt_neg ? '-' : '+'); if (expt < 10) /* Exponent always has at least two digits. */ put ('0'); do { j /= 10; put ('0' + (expt / j)); expt %= j; } while (j > 1); } else { /* Decimal fraction notation. */ if (k < 0) { put ('0'); if (prec > 0 || info->alt) put (*decimal); /* Write leading fractional zeros. */ j = 0; while (--j > k) put ('0'); } put (digit); if (!low && !high && k != cutoff) { int stop; do { stop = hack_digit (); if (k == -1) put (*decimal); put (digit); } while (! stop); } while (k > 0) { put ('0'); --k; } if ((type != 'g' && prec > 0) || info->alt) { if (k == 0) put (*decimal); while (k-- > -prec) put ('0'); } } }#undef put /* The number is all converted in BUF. Now write it with sign and appropriate padding. */ if (is_neg || info->showsign || info->space) --width; width -= bp - buf; if (!info->left && info->pad == ' ') /* Pad with spaces on the left. */ while (width-- > 0) outchar (' '); /* Write the sign. */ if (is_neg) outchar ('-'); else if (info->showsign) outchar ('+'); else if (info->space) outchar (' '); if (!info->left && info->pad == '0') /* Pad with zeros on the left. */ while (width-- > 0) outchar ('0'); if (fwrite (buf, bp - buf, 1, s) != 1) return -1; done += bp - buf; if (info->left) /* Pad with spaces on the right. */ while (width-- > 0) outchar (' '); return done;}#ifndef NDEBUGstatic voidmpn_dump (str, p, size) const char *str; mp_limb *p; mp_size_t size;{ fprintf (stderr, "%s = ", str); while (size != 0) { size--; fprintf (stderr, "%08lX", p[size]); } fprintf (stderr, "\n");}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -