summaryrefslogtreecommitdiff
path: root/printf
diff options
context:
space:
mode:
authorKevin Ryde <user42@zip.com.au>2001-07-30 22:57:22 +0200
committerKevin Ryde <user42@zip.com.au>2001-07-30 22:57:22 +0200
commitc870bb57a36d9f57d4c982431c4545b5bf887ca5 (patch)
treed812ac62a465a04869249ba04729519a624606cf /printf
parent0a88a1a41a611f644f83058940023f6d6e79b0a1 (diff)
downloadgmp-c870bb57a36d9f57d4c982431c4545b5bf887ca5.tar.gz
More of initial checkin.
Diffstat (limited to 'printf')
-rw-r--r--printf/doprnt.c17
-rw-r--r--printf/doprntf.c34
2 files changed, 37 insertions, 14 deletions
diff --git a/printf/doprnt.c b/printf/doprnt.c
index 0bd0603aa..8575cb663 100644
--- a/printf/doprnt.c
+++ b/printf/doprnt.c
@@ -132,7 +132,7 @@ __gmp_doprnt (const struct doprnt_funs_t *funs, void *data,
size_t alloc_fmt_size;
char *fmt, *alloc_fmt, *last_fmt, *this_fmt;
int retval = 0;
- int type, fchar, *value;
+ int type, fchar, *value, seen_precision;
struct doprnt_params_t param;
TRACE (printf ("gmp_doprnt \"%s\"\n", orig_fmt));
@@ -177,6 +177,7 @@ __gmp_doprnt (const struct doprnt_funs_t *funs, void *data,
param.showtrailing = 1;
param.sign = '\0';
param.width = 0;
+ seen_precision = 0;
/* This loop parses a single % sequence. "break" from the switch
means continue with this %, "goto next" means the conversion
@@ -189,7 +190,11 @@ __gmp_doprnt (const struct doprnt_funs_t *funs, void *data,
break;
switch (fchar) {
+
case 'a':
+ /* %a behaves like %e, but defaults to all significant digits,
+ and there's no leading zeros on the exponent (which is in
+ fact bit-based) */
param.base = 16;
param.expfmt = "p%c%d";
goto conv_a;
@@ -199,8 +204,10 @@ __gmp_doprnt (const struct doprnt_funs_t *funs, void *data,
conv_a:
param.conv = DOPRNT_CONV_SCIENTIFIC;
param.exptimes4 = 1;
+ if (! seen_precision)
+ param.prec = -1; /* default to all digits */
param.showbase = DOPRNT_SHOWBASE_YES;
- param.showtrailing = 0;
+ param.showtrailing = 1;
goto floating;
case 'c':
@@ -303,10 +310,7 @@ __gmp_doprnt (const struct doprnt_funs_t *funs, void *data,
int ndigits, ret;
FLUSH ();
f = va_arg (ap, mpf_srcptr);
- if (fchar == 'a' || fchar == 'A')
- ndigits = 0; /* all significant digits */
- else
- ndigits = __gmp_doprnt_float_digits (&param, f);
+ ndigits = __gmp_doprnt_float_digits (&param, f);
s = mpf_get_str (NULL, &exp, param.base, ndigits, f);
ASSERT_DOPRNT_NDIGITS (param, ndigits, exp);
ret = __gmp_doprnt_float (funs, data, &param, s, exp);
@@ -410,6 +414,7 @@ __gmp_doprnt (const struct doprnt_funs_t *funs, void *data,
param.justify = DOPRNT_JUSTIFY_LEFT;
break;
case '.':
+ seen_precision = 1;
value = &param.prec;
break;
diff --git a/printf/doprntf.c b/printf/doprntf.c
index 83a31c86f..73dd617cd 100644
--- a/printf/doprntf.c
+++ b/printf/doprntf.c
@@ -54,6 +54,10 @@ __gmp_doprnt_float_digits (const struct doprnt_params_t *p,
{
int ndigits;
+ /* all significant digits */
+ if (p->prec == -1)
+ return 0;
+
ASSERT (p->prec >= 0);
switch (p->conv) {
@@ -105,7 +109,7 @@ __gmp_doprnt_float (const struct doprnt_funs_t *funs,
char *s,
mp_exp_t exp)
{
- int len, newlen, justify, sign, justlen, explen, showbaselen;
+ int len, prec, newlen, justify, sign, justlen, explen, showbaselen;
int signlen, intlen, intzeros, pointlen, fraczeros, fraclen, preczeros;
int retval = 0;
char exponent[BITS_PER_MP_LIMB + 10];
@@ -113,6 +117,7 @@ __gmp_doprnt_float (const struct doprnt_funs_t *funs,
const char *point;
len = strlen (s);
+ prec = p->prec;
TRACE (printf ("__gmp_doprnt_float\n");
printf (" s %s\n", s);
@@ -130,9 +135,12 @@ __gmp_doprnt_float (const struct doprnt_funs_t *funs,
switch (p->conv) {
case DOPRNT_CONV_FIXED:
- /* Truncate if necessary so fraction will be at most p->prec digits. */
- ASSERT (p->prec >= 0);
- newlen = exp + p->prec;
+ if (prec == -1)
+ prec = MAX (0, len-exp); /* retain all digits */
+
+ /* Truncate if necessary so fraction will be at most prec digits. */
+ ASSERT (prec >= 0);
+ newlen = exp + prec;
if (newlen < 0)
{
/* first non-zero digit is below target prec, and at least one zero
@@ -222,6 +230,10 @@ __gmp_doprnt_float (const struct doprnt_funs_t *funs,
{
int expval;
char expsign;
+
+ if (prec == -1)
+ prec = MAX (0, len-1); /* retain all digits */
+
scientific:
TRACE (printf (" scientific s.sss\n"));
@@ -258,12 +270,15 @@ __gmp_doprnt_float (const struct doprnt_funs_t *funs,
/*FALLTHRU*/ /* to stop variables looking uninitialized */
case DOPRNT_CONV_GENERAL:
+ if (prec == -1)
+ prec = len; /* retain all digits */
+
/* The exponent for "scientific" will be exp-1, choose scientific if
this is < -4 or >= prec (and minimum 1 for prec). For f==0 will have
exp==0 and get the desired "fixed". This rule follows glibc. For
fixed there's no need to truncate, the desired ndigits will already
be as required. */
- if (exp-1 < -4 || exp-1 >= MAX (1, p->prec))
+ if (exp-1 < -4 || exp-1 >= MAX (1, prec))
goto scientific;
else
goto fixed;
@@ -271,12 +286,15 @@ __gmp_doprnt_float (const struct doprnt_funs_t *funs,
TRACE (printf (" intlen %d fraczeros %d fraclen %d\n",
intlen, fraczeros, fraclen));
+ ASSERT (p->prec == -1
+ ? intlen + fraclen == strlen (s)
+ : intlen + fraclen <= strlen (s));
if (p->showtrailing)
{
/* Pad to requested precision with trailing zeros, for general this is
all digits, for fixed and scientific just the fraction. */
- preczeros = p->prec - (fraczeros + fraclen
+ preczeros = prec - (fraczeros + fraclen
+ (p->conv == DOPRNT_CONV_GENERAL
? intlen + intzeros : 0));
preczeros = MAX (0, preczeros);
@@ -284,7 +302,7 @@ __gmp_doprnt_float (const struct doprnt_funs_t *funs,
else
preczeros = 0;
TRACE (printf (" prec=%d showtrailing=%d, pad with preczeros %d\n",
- p->prec, p->showtrailing, preczeros));
+ prec, p->showtrailing, preczeros));
/* radix point if needed, or if forced */
point = ".";
@@ -308,7 +326,7 @@ __gmp_doprnt_float (const struct doprnt_funs_t *funs,
case DOPRNT_SHOWBASE_NO:
break;
case DOPRNT_SHOWBASE_NONZERO:
- if (len == 0)
+ if (intlen == 0)
break;
/*FALLTHRU*/
case DOPRNT_SHOWBASE_YES: