📄 snprintf.c
字号:
return (0.); } /* negative number ? */ if (real < 0.) real = -real; /* a fraction ? */ if ( real < 1.) { *ip = 0.; return real; } /* the real work :-) */ for (j = log_10(real); j >= 0; j--) { p = pow_10(j); s = (real - real_integral)/p; i = 0.; while (i + 1. <= s) i++; real_integral += i*p; } *ip = real_integral; return (real - real_integral);}#define PRECISION 1.e-6/* * return an ascii representation of the integral part of the number * and set fract to be an ascii representation of the fraction part * the container for the fraction and the integral part or staticly * declare with fix size */static char *numtoa(number, base, precision, fract) double number; int base, precision; char **fract;{ register int i, j; double ip, fp; /* integer and fraction part */ double fraction; int digits = MAX_INT - 1; static char integral_part[MAX_INT]; static char fraction_part[MAX_FRACT]; double sign; int ch; /* taking care of the obvious case: 0.0 */ if (number == 0.) { integral_part[0] = '0'; integral_part[1] = '\0'; /* The fractional part has to take the precision into account */ for (ch = 0; ch < precision-1; ch++) fraction_part[ch] = '0'; fraction_part[ch] = '0'; fraction_part[ch+1] = '\0'; if (fract) *fract = fraction_part; return integral_part; } /* for negative numbers */ if ((sign = number) < 0.) { number = -number; digits--; /* sign consume one digit */ } fraction = integral(number, &ip); number = ip; /* do the integral part */ if (ip == 0.) { integral_part[0] = '0'; i = 1; } else { for ( i = 0; i < digits && number != 0.; ++i) { number /= base; fp = integral(number, &ip); ch = (int)((fp + PRECISION)*base); /* force to round */ integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10; if (! ISXDIGIT((unsigned char)integral_part[i])) break; /* bail out overflow !! */ number = ip; } } /* Oh No !! out of bound, ho well fill it up ! */ if (number != 0.) for (i = 0; i < digits; ++i) integral_part[i] = '9'; /* put the sign ? */ if (sign < 0.) integral_part[i++] = '-'; integral_part[i] = '\0'; /* reverse every thing */ for ( i--, j = 0; j < i; j++, i--) SWAP_INT(integral_part[i], integral_part[j]); /* the fractional part */ for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision--) { fraction_part[i] = (int)((fp + PRECISION)*10. + '0'); if (! DIGIT(fraction_part[i])) /* underflow ? */ break; fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.); } fraction_part[i] = '\0'; if (fract != (char **)0) *fract = fraction_part; return integral_part;}#endif/* for %d and friends, it puts in holder * the representation with the right padding */static voidnumber(p, d, base) struct DATA *p; unsigned long d; int base;{ char *tmp, *t; long sd; int flags; /* An explicit precision turns off the zero-padding flag. */ if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT)) p->flags &= ~PF_ZEROPAD; sd = d; /* signed for ' ' padding in base 10 */ flags = 0; flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; if (*p->pf == 'X') flags |= FL_HEXUPPER; tmp = fmtulong (d, base, intbuf, sizeof(intbuf), flags); t = 0; if ((p->flags & PF_THOUSANDS)) { GETLOCALEDATA(decpoint, thoussep, grouping); if (grouping && (t = groupnum (tmp))) tmp = t; } p->width -= strlen(tmp); PAD_RIGHT(p); if ((p->flags & PF_DOT) && p->precision > 0) { p->precision -= strlen(tmp); PAD_ZERO(p); } switch (base) { case 10: PUT_PLUS(sd, p, 0); PUT_SPACE(sd, p, 0); break; case 8: if (p->flags & PF_ALTFORM) PUT_CHAR('0', p); break; case 16: if (p->flags & PF_ALTFORM) { PUT_CHAR('0', p); PUT_CHAR(*p->pf, p); } break; } while (*tmp) { PUT_CHAR(*tmp, p); tmp++; } PAD_LEFT(p); FREE (t);}#ifdef HAVE_LONG_LONG/* * identical to number() but works for `long long' */static voidlnumber(p, d, base) struct DATA *p; unsigned long long d; int base;{ char *tmp, *t; long long sd; int flags; /* An explicit precision turns off the zero-padding flag. */ if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT)) p->flags &= ~PF_ZEROPAD; sd = d; /* signed for ' ' padding in base 10 */ flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; if (*p->pf == 'X') flags |= FL_HEXUPPER; tmp = fmtullong (d, base, intbuf, sizeof(intbuf), flags); t = 0; if ((p->flags & PF_THOUSANDS)) { GETLOCALEDATA(decpoint, thoussep, grouping); if (grouping && (t = groupnum (tmp))) tmp = t; } p->width -= strlen(tmp); PAD_RIGHT(p); if ((p->flags & PF_DOT) && p->precision > 0) { p->precision -= strlen(tmp); PAD_ZERO(p); } switch (base) { case 10: PUT_PLUS(sd, p, 0); PUT_SPACE(sd, p, 0); break; case 8: if (p->flags & PF_ALTFORM) PUT_CHAR('0', p); break; case 16: if (p->flags & PF_ALTFORM) { PUT_CHAR('0', p); PUT_CHAR(*p->pf, p); } break; } while (*tmp) { PUT_CHAR(*tmp, p); tmp++; } PAD_LEFT(p); FREE (t);}#endifstatic voidpointer(p, d) struct DATA *p; unsigned long d;{ char *tmp; tmp = fmtulong(d, 16, intbuf, sizeof(intbuf), 0); p->width -= strlen(tmp); PAD_RIGHT(p); /* prefix '0x' for pointers */ PUT_CHAR('0', p); PUT_CHAR('x', p); while (*tmp) { PUT_CHAR(*tmp, p); tmp++; } PAD_LEFT(p);}/* %s strings */static voidstrings(p, tmp) struct DATA *p; char *tmp;{ size_t len; len = strlen(tmp); if (p->precision != NOT_FOUND) /* the smallest number */ len = (len < p->precision ? len : p->precision); p->width -= len; PUT_STRING (tmp, len, p);}#if HANDLE_MULTIBYTE/* %ls wide-character strings */static voidwstrings(p, tmp) struct DATA *p; wchar_t *tmp;{ size_t len; mbstate_t mbs; char *os; const wchar_t *ws; memset (&mbs, '\0', sizeof (mbstate_t)); ws = (const wchar_t *)tmp; os = (char *)NULL; if (p->precision != NOT_FOUND) { os = (char *)xmalloc (p->precision + 1); len = wcsrtombs (os, &ws, p->precision, &mbs); } else { len = wcsrtombs (NULL, &ws, 0, &mbs); if (len != (size_t)-1) { memset (&mbs, '\0', sizeof (mbstate_t)); os = (char *)xmalloc (len + 1); (void)wcsrtombs (os, &ws, len + 1, &mbs); } } if (len == (size_t)-1) { /* invalid multibyte sequence; bail now. */ FREE (os); return; } p->width -= len; PUT_STRING (os, len, p); free (os);}static voidwchars (p, wc) struct DATA *p; wint_t wc;{ char *lbuf, *l; mbstate_t mbs; size_t len; lbuf = (char *)malloc (MB_CUR_MAX+1); if (lbuf == 0) return; memset (&mbs, '\0', sizeof (mbstate_t)); len = wcrtomb (lbuf, wc, &mbs); if (len == (size_t)-1) /* conversion failed; bail now. */ return; p->width -= len; l = lbuf; PUT_STRING (l, len, p); free (lbuf);}#endif /* HANDLE_MULTIBYTE */#ifdef FLOATING_POINT#ifndef HAVE_ISINF_IN_LIBC/* Half-assed versions, since we don't want to link with libm. */static intisinf(d) double d;{#ifdef DBL_MAX if (d < DBL_MIN) return -1; else if (d > DBL_MAX) return 1; else#endif return 0;}#endif#ifndef HAVE_ISNAN_IN_LIBCstatic intisnan(d) double d;{ return 0;}#endif/* Check for [+-]infinity and NaN. If MODE == 1, we check for Infinity, else (mode == 2) we check for NaN. This does the necessary printing. Returns 1 if Inf or Nan, 0 if not. */static intchkinfnan(p, d, mode) struct DATA *p; double d; int mode; /* == 1 for inf, == 2 for nan */{ int i; char *tmp; char *big, *small; i = (mode == 1) ? isinf(d) : isnan(d); if (i == 0) return 0; big = (mode == 1) ? "INF" : "NAN"; small = (mode == 1) ? "inf" : "nan"; tmp = (*p->pf == 'F' || *p->pf == 'G' || *p->pf == 'E') ? big : small; if (i < 0) PUT_CHAR('-', p); while (*tmp) { PUT_CHAR (*tmp, p); tmp++; } return 1;}/* %f %F %g %G floating point representation */static voidfloating(p, d) struct DATA *p; double d;{ char *tmp, *tmp2, *t; int i; if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))) return; /* already printed nan or inf */ GETLOCALEDATA(decpoint, thoussep, grouping); DEF_PREC(p); d = ROUND(d, p); tmp = dtoa(d, p->precision, &tmp2); t = 0; if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp))) tmp = t; if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) { /* smash the trailing zeros unless altform */ for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) tmp2[i] = '\0'; if (tmp2[0] == '\0') p->precision = 0; } /* calculate the padding. 1 for the dot */ p->width = p->width - ((d > 0. && p->justify == RIGHT) ? 1:0) - ((p->flags & PF_SPACE) ? 1:0) - strlen(tmp) - p->precision - ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */ PAD_RIGHT(p); PUT_PLUS(d, p, 0.); PUT_SPACE(d, p, 0.); while (*tmp) { PUT_CHAR(*tmp, p); /* the integral */ tmp++; } FREE (t); if (p->precision != 0 || (p->flags & PF_ALTFORM)) PUT_CHAR(decpoint, p); /* put the '.' */ for (; *tmp2; tmp2++) PUT_CHAR(*tmp2, p); /* the fraction */ PAD_LEFT(p);} /* %e %E %g %G exponent representation */static voidexponent(p, d) struct DATA *p; double d;{ char *tmp, *tmp2; int j, i; if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))) return; /* already printed nan or inf */ GETLOCALEDATA(decpoint, thoussep, grouping); DEF_PREC(p); if (d == 0.) j = 0; else { j = log_10(d); d = d / pow_10(j); /* get the Mantissa */ d = ROUND(d, p); } tmp = dtoa(d, p->precision, &tmp2); /* 1 for unit, 1 for the '.', 1 for 'e|E', * 1 for '+|-', 2 for 'exp' */ /* calculate how much padding need */ p->width = p->width - ((d > 0. && p->justify == RIGHT) ? 1:0) - ((p->flags & PF_SPACE) ? 1:0) - p->precision - 6; PAD_RIGHT(p); PUT_PLUS(d, p, 0.); PUT_SPACE(d, p, 0.); while (*tmp) { PUT_CHAR(*tmp, p); tmp++; } if (p->precision != 0 || (p->flags & PF_ALTFORM)) PUT_CHAR(decpoint, p); /* the '.' */ if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) /* smash the trailing zeros unless altform */ for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) tmp2[i] = '\0'; for (; *tmp2; tmp2++) PUT_CHAR(*tmp2, p); /* the fraction */ /* the exponent put the 'e|E' */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -