Home | History | Annotate | Line # | Download | only in printf
      1      1.1  mrg /* Print floating point number in hexadecimal notation according to ISO C99.
      2      1.1  mrg    Copyright (C) 1997-2012 Free Software Foundation, Inc.
      3      1.1  mrg    This file is part of the GNU C Library.
      4      1.1  mrg    Contributed by Ulrich Drepper <drepper (at) cygnus.com>, 1997.
      5      1.1  mrg 
      6      1.1  mrg    The GNU C Library is free software; you can redistribute it and/or
      7      1.1  mrg    modify it under the terms of the GNU Lesser General Public
      8      1.1  mrg    License as published by the Free Software Foundation; either
      9      1.1  mrg    version 2.1 of the License, or (at your option) any later version.
     10      1.1  mrg 
     11      1.1  mrg    The GNU C Library is distributed in the hope that it will be useful,
     12      1.1  mrg    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1  mrg    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14      1.1  mrg    Lesser General Public License for more details.
     15      1.1  mrg 
     16      1.1  mrg    You should have received a copy of the GNU Lesser General Public
     17      1.1  mrg    License along with the GNU C Library; if not, see
     18      1.1  mrg    <http://www.gnu.org/licenses/>.  */
     19      1.1  mrg 
     20      1.1  mrg #include <config.h>
     21      1.1  mrg #include <math.h>
     22      1.1  mrg #include <stdlib.h>
     23      1.1  mrg #include <stdio.h>
     24      1.1  mrg #include <string.h>
     25      1.1  mrg #include <stdbool.h>
     26      1.1  mrg #define NDEBUG
     27      1.1  mrg #include <assert.h>
     28      1.1  mrg #include "quadmath-rounding-mode.h"
     29      1.1  mrg #include "quadmath-printf.h"
     30      1.1  mrg #include "_itoa.h"
     31      1.1  mrg #include "_itowa.h"
     32      1.1  mrg 
     33      1.1  mrg 
     34      1.1  mrg /* Macros for doing the actual output.  */
     36      1.1  mrg 
     37      1.1  mrg #define outchar(ch)							      \
     38      1.1  mrg   do									      \
     39      1.1  mrg     {									      \
     40      1.1  mrg       register const int outc = (ch);					      \
     41      1.1  mrg       if (PUTC (outc, fp) == EOF)					      \
     42      1.1  mrg 	return -1;							      \
     43      1.1  mrg       ++done;								      \
     44      1.1  mrg     } while (0)
     45      1.1  mrg 
     46      1.1  mrg #define PRINT(ptr, wptr, len)						      \
     47      1.1  mrg   do									      \
     48      1.1  mrg     {									      \
     49      1.1  mrg       register size_t outlen = (len);					      \
     50      1.1  mrg       if (wide)								      \
     51      1.1  mrg 	while (outlen-- > 0)						      \
     52      1.1  mrg 	  outchar (*wptr++);						      \
     53      1.1  mrg       else								      \
     54      1.1  mrg 	while (outlen-- > 0)						      \
     55      1.1  mrg 	  outchar (*ptr++);						      \
     56      1.1  mrg     } while (0)
     57      1.1  mrg 
     58      1.1  mrg #define PADN(ch, len)							      \
     59      1.1  mrg   do									      \
     60      1.1  mrg     {									      \
     61      1.1  mrg       if (PAD (fp, ch, len) != len)					      \
     62      1.1  mrg 	return -1;							      \
     63      1.1  mrg       done += len;							      \
     64      1.1  mrg     }									      \
     65      1.1  mrg   while (0)
     66      1.1  mrg 
     67      1.1  mrg 
     68      1.1  mrg 
     70      1.1  mrg int
     71      1.1  mrg __quadmath_printf_fphex (struct __quadmath_printf_file *fp,
     72      1.1  mrg 			 const struct printf_info *info,
     73      1.1  mrg 			 const void *const *args)
     74      1.1  mrg {
     75      1.1  mrg   /* The floating-point value to output.  */
     76      1.1  mrg   ieee854_float128 fpnum;
     77      1.1  mrg 
     78      1.1  mrg   /* Locale-dependent representation of decimal point.	*/
     79      1.1  mrg   const char *decimal;
     80      1.1  mrg   wchar_t decimalwc;
     81      1.1  mrg 
     82      1.1  mrg   /* "NaN" or "Inf" for the special cases.  */
     83      1.1  mrg   const char *special = NULL;
     84      1.1  mrg   const wchar_t *wspecial = NULL;
     85      1.1  mrg 
     86      1.1  mrg   /* Buffer for the generated number string for the mantissa.  The
     87      1.1  mrg      maximal size for the mantissa is 128 bits.  */
     88      1.1  mrg   char numbuf[32];
     89      1.1  mrg   char *numstr;
     90      1.1  mrg   char *numend;
     91      1.1  mrg   wchar_t wnumbuf[32];
     92      1.1  mrg   wchar_t *wnumstr;
     93      1.1  mrg   wchar_t *wnumend;
     94      1.1  mrg   int negative;
     95      1.1  mrg 
     96      1.1  mrg   /* The maximal exponent of two in decimal notation has 5 digits.  */
     97      1.1  mrg   char expbuf[5];
     98      1.1  mrg   char *expstr;
     99      1.1  mrg   wchar_t wexpbuf[5];
    100      1.1  mrg   wchar_t *wexpstr;
    101      1.1  mrg   int expnegative;
    102      1.1  mrg   int exponent;
    103      1.1  mrg 
    104      1.1  mrg   /* Non-zero is mantissa is zero.  */
    105      1.1  mrg   int zero_mantissa;
    106      1.1  mrg 
    107      1.1  mrg   /* The leading digit before the decimal point.  */
    108      1.1  mrg   char leading;
    109      1.1  mrg 
    110      1.1  mrg   /* Precision.  */
    111      1.1  mrg   int precision = info->prec;
    112      1.1  mrg 
    113      1.1  mrg   /* Width.  */
    114      1.1  mrg   int width = info->width;
    115      1.1  mrg 
    116      1.1  mrg   /* Number of characters written.  */
    117      1.1  mrg   int done = 0;
    118      1.1  mrg 
    119      1.1  mrg   /* Nonzero if this is output on a wide character stream.  */
    120      1.1  mrg   int wide = info->wide;
    121      1.1  mrg 
    122      1.1  mrg   bool do_round_away;
    123      1.1  mrg 
    124      1.1  mrg   /* Figure out the decimal point character.  */
    125      1.1  mrg #ifdef USE_NL_LANGINFO
    126      1.1  mrg   if (info->extra == 0)
    127      1.1  mrg     decimal = nl_langinfo (DECIMAL_POINT);
    128      1.1  mrg   else
    129      1.1  mrg     {
    130      1.1  mrg       decimal = nl_langinfo (MON_DECIMAL_POINT);
    131      1.1  mrg       if (*decimal == '\0')
    132      1.1  mrg 	decimal = nl_langinfo (DECIMAL_POINT);
    133      1.1  mrg     }
    134      1.1  mrg   /* The decimal point character must never be zero.  */
    135      1.1  mrg   assert (*decimal != '\0');
    136      1.1  mrg #elif defined USE_LOCALECONV
    137      1.1  mrg   const struct lconv *lc = localeconv ();
    138      1.1  mrg   if (info->extra == 0)
    139      1.1  mrg     decimal = lc->decimal_point;
    140      1.1  mrg   else
    141      1.1  mrg     {
    142      1.1  mrg       decimal = lc->mon_decimal_point;
    143      1.1  mrg       if (decimal == NULL || *decimal == '\0')
    144      1.1  mrg 	decimal = lc->decimal_point;
    145      1.1  mrg     }
    146      1.1  mrg   if (decimal == NULL || *decimal == '\0')
    147      1.1  mrg     decimal = ".";
    148      1.1  mrg #else
    149      1.1  mrg   decimal = ".";
    150      1.1  mrg #endif
    151      1.1  mrg #ifdef USE_NL_LANGINFO_WC
    152      1.1  mrg   if (info->extra == 0)
    153      1.1  mrg     decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
    154      1.1  mrg   else
    155      1.1  mrg     {
    156      1.1  mrg       decimalwc = nl_langinfo_wc (_NL_MONETARY_DECIMAL_POINT_WC);
    157      1.1  mrg       if (decimalwc == L_('\0'))
    158      1.1  mrg 	decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
    159      1.1  mrg     }
    160      1.1  mrg   /* The decimal point character must never be zero.  */
    161      1.1  mrg   assert (decimalwc != L_('\0'));
    162      1.1  mrg #else
    163      1.1  mrg   decimalwc = L_('.');
    164      1.1  mrg #endif
    165      1.1  mrg 
    166  1.1.1.2  mrg   /* Fetch the argument value.	*/
    167  1.1.1.2  mrg     {
    168      1.1  mrg       memcpy (&fpnum.value, *(const void *const *) args[0],
    169      1.1  mrg 	      sizeof (fpnum.value));
    170      1.1  mrg 
    171      1.1  mrg       /* Check for special values: not a number or infinity.  */
    172      1.1  mrg       if (isnanq (fpnum.value))
    173      1.1  mrg 	{
    174      1.1  mrg 	  negative = fpnum.ieee.negative != 0;
    175      1.1  mrg 	  if (isupper (info->spec))
    176      1.1  mrg 	    {
    177      1.1  mrg 	      special = "NAN";
    178      1.1  mrg 	      wspecial = L_("NAN");
    179      1.1  mrg 	    }
    180      1.1  mrg 	  else
    181      1.1  mrg 	    {
    182      1.1  mrg 	      special = "nan";
    183      1.1  mrg 	      wspecial = L_("nan");
    184      1.1  mrg 	    }
    185      1.1  mrg 	}
    186      1.1  mrg       else
    187      1.1  mrg 	{
    188      1.1  mrg 	  if (isinfq (fpnum.value))
    189      1.1  mrg 	    {
    190      1.1  mrg 	      if (isupper (info->spec))
    191      1.1  mrg 		{
    192      1.1  mrg 		  special = "INF";
    193      1.1  mrg 		  wspecial = L_("INF");
    194      1.1  mrg 		}
    195      1.1  mrg 	      else
    196      1.1  mrg 		{
    197      1.1  mrg 		  special = "inf";
    198      1.1  mrg 		  wspecial = L_("inf");
    199      1.1  mrg 		}
    200      1.1  mrg 	    }
    201      1.1  mrg 
    202      1.1  mrg 	  negative = signbitq (fpnum.value);
    203      1.1  mrg 	}
    204      1.1  mrg     }
    205      1.1  mrg 
    206      1.1  mrg   if (special)
    207      1.1  mrg     {
    208      1.1  mrg       int width = info->width;
    209      1.1  mrg 
    210      1.1  mrg       if (negative || info->showsign || info->space)
    211      1.1  mrg 	--width;
    212      1.1  mrg       width -= 3;
    213      1.1  mrg 
    214      1.1  mrg       if (!info->left && width > 0)
    215      1.1  mrg 	PADN (' ', width);
    216      1.1  mrg 
    217      1.1  mrg       if (negative)
    218      1.1  mrg 	outchar ('-');
    219      1.1  mrg       else if (info->showsign)
    220      1.1  mrg 	outchar ('+');
    221      1.1  mrg       else if (info->space)
    222      1.1  mrg 	outchar (' ');
    223      1.1  mrg 
    224      1.1  mrg       PRINT (special, wspecial, 3);
    225      1.1  mrg 
    226      1.1  mrg       if (info->left && width > 0)
    227      1.1  mrg 	PADN (' ', width);
    228      1.1  mrg 
    229      1.1  mrg       return done;
    230      1.1  mrg     }
    231      1.1  mrg 
    232      1.1  mrg     {
    233      1.1  mrg       /* We have 112 bits of mantissa plus one implicit digit.  Since
    234      1.1  mrg 	 112 bits are representable without rest using hexadecimal
    235      1.1  mrg 	 digits we use only the implicit digits for the number before
    236      1.1  mrg 	 the decimal point.  */
    237      1.1  mrg       uint64_t num0, num1;
    238      1.1  mrg 
    239      1.1  mrg       assert (sizeof (long double) == 16);
    240      1.1  mrg 
    241      1.1  mrg       num0 = (((unsigned long long int) fpnum.ieee.mantissa0) << 32
    242      1.1  mrg 	      | fpnum.ieee.mantissa1);
    243      1.1  mrg       num1 = (((unsigned long long int) fpnum.ieee.mantissa2) << 32
    244      1.1  mrg 	      | fpnum.ieee.mantissa3);
    245      1.1  mrg 
    246      1.1  mrg       zero_mantissa = (num0|num1) == 0;
    247      1.1  mrg 
    248      1.1  mrg       if (sizeof (unsigned long int) > 6)
    249      1.1  mrg 	{
    250      1.1  mrg 	  numstr = _itoa_word (num1, numbuf + sizeof numbuf, 16,
    251      1.1  mrg 			       info->spec == 'A');
    252      1.1  mrg 	  wnumstr = _itowa_word (num1,
    253      1.1  mrg 				 wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),
    254      1.1  mrg 				 16, info->spec == 'A');
    255      1.1  mrg 	}
    256      1.1  mrg       else
    257      1.1  mrg 	{
    258      1.1  mrg 	  numstr = _itoa (num1, numbuf + sizeof numbuf, 16,
    259      1.1  mrg 			  info->spec == 'A');
    260      1.1  mrg 	  wnumstr = _itowa (num1,
    261      1.1  mrg 			    wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),
    262      1.1  mrg 			    16, info->spec == 'A');
    263      1.1  mrg 	}
    264      1.1  mrg 
    265      1.1  mrg       while (numstr > numbuf + (sizeof numbuf - 64 / 4))
    266      1.1  mrg 	{
    267      1.1  mrg 	  *--numstr = '0';
    268      1.1  mrg 	  *--wnumstr = L_('0');
    269      1.1  mrg 	}
    270      1.1  mrg 
    271      1.1  mrg       if (sizeof (unsigned long int) > 6)
    272      1.1  mrg 	{
    273      1.1  mrg 	  numstr = _itoa_word (num0, numstr, 16, info->spec == 'A');
    274      1.1  mrg 	  wnumstr = _itowa_word (num0, wnumstr, 16, info->spec == 'A');
    275      1.1  mrg 	}
    276      1.1  mrg       else
    277      1.1  mrg 	{
    278      1.1  mrg 	  numstr = _itoa (num0, numstr, 16, info->spec == 'A');
    279      1.1  mrg 	  wnumstr = _itowa (num0, wnumstr, 16, info->spec == 'A');
    280      1.1  mrg 	}
    281      1.1  mrg 
    282      1.1  mrg       /* Fill with zeroes.  */
    283      1.1  mrg       while (numstr > numbuf + (sizeof numbuf - 112 / 4))
    284      1.1  mrg 	{
    285      1.1  mrg 	  *--wnumstr = L_('0');
    286      1.1  mrg 	  *--numstr = '0';
    287      1.1  mrg 	}
    288      1.1  mrg 
    289      1.1  mrg       leading = fpnum.ieee.exponent == 0 ? '0' : '1';
    290      1.1  mrg 
    291      1.1  mrg       exponent = fpnum.ieee.exponent;
    292      1.1  mrg 
    293      1.1  mrg       if (exponent == 0)
    294      1.1  mrg 	{
    295      1.1  mrg 	  if (zero_mantissa)
    296      1.1  mrg 	    expnegative = 0;
    297      1.1  mrg 	  else
    298      1.1  mrg 	    {
    299      1.1  mrg 	      /* This is a denormalized number.  */
    300      1.1  mrg 	      expnegative = 1;
    301      1.1  mrg 	      exponent = IEEE854_FLOAT128_BIAS - 1;
    302      1.1  mrg 	    }
    303      1.1  mrg 	}
    304      1.1  mrg       else if (exponent >= IEEE854_FLOAT128_BIAS)
    305      1.1  mrg 	{
    306      1.1  mrg 	  expnegative = 0;
    307      1.1  mrg 	  exponent -= IEEE854_FLOAT128_BIAS;
    308      1.1  mrg 	}
    309      1.1  mrg       else
    310      1.1  mrg 	{
    311      1.1  mrg 	  expnegative = 1;
    312      1.1  mrg 	  exponent = -(exponent - IEEE854_FLOAT128_BIAS);
    313      1.1  mrg 	}
    314      1.1  mrg     }
    315      1.1  mrg 
    316      1.1  mrg   /* Look for trailing zeroes.  */
    317      1.1  mrg   if (! zero_mantissa)
    318      1.1  mrg     {
    319      1.1  mrg       wnumend = &wnumbuf[sizeof wnumbuf / sizeof wnumbuf[0]];
    320      1.1  mrg       numend = &numbuf[sizeof numbuf / sizeof numbuf[0]];
    321      1.1  mrg       while (wnumend[-1] == L_('0'))
    322      1.1  mrg 	{
    323      1.1  mrg 	  --wnumend;
    324      1.1  mrg 	  --numend;
    325      1.1  mrg 	}
    326      1.1  mrg 
    327      1.1  mrg       do_round_away = false;
    328      1.1  mrg 
    329      1.1  mrg       if (precision != -1 && precision < numend - numstr)
    330      1.1  mrg 	{
    331      1.1  mrg 	  char last_digit = precision > 0 ? numstr[precision - 1] : leading;
    332      1.1  mrg 	  char next_digit = numstr[precision];
    333      1.1  mrg 	  int last_digit_value = (last_digit >= 'A' && last_digit <= 'F'
    334      1.1  mrg 				  ? last_digit - 'A' + 10
    335      1.1  mrg 				  : (last_digit >= 'a' && last_digit <= 'f'
    336      1.1  mrg 				     ? last_digit - 'a' + 10
    337      1.1  mrg 				     : last_digit - '0'));
    338      1.1  mrg 	  int next_digit_value = (next_digit >= 'A' && next_digit <= 'F'
    339      1.1  mrg 				  ? next_digit - 'A' + 10
    340      1.1  mrg 				  : (next_digit >= 'a' && next_digit <= 'f'
    341      1.1  mrg 				     ? next_digit - 'a' + 10
    342      1.1  mrg 				     : next_digit - '0'));
    343      1.1  mrg 	  bool more_bits = ((next_digit_value & 7) != 0
    344      1.1  mrg 			    || precision + 1 < numend - numstr);
    345      1.1  mrg #ifdef HAVE_FENV_H
    346      1.1  mrg 	  int rounding_mode = get_rounding_mode ();
    347      1.1  mrg 	  do_round_away = round_away (negative, last_digit_value & 1,
    348      1.1  mrg 				      next_digit_value >= 8, more_bits,
    349      1.1  mrg 				      rounding_mode);
    350      1.1  mrg #endif
    351      1.1  mrg 	}
    352      1.1  mrg 
    353      1.1  mrg       if (precision == -1)
    354      1.1  mrg 	precision = numend - numstr;
    355      1.1  mrg       else if (do_round_away)
    356      1.1  mrg 	{
    357      1.1  mrg 	  /* Round up.  */
    358      1.1  mrg 	  int cnt = precision;
    359      1.1  mrg 	  while (--cnt >= 0)
    360      1.1  mrg 	    {
    361      1.1  mrg 	      char ch = numstr[cnt];
    362      1.1  mrg 	      /* We assume that the digits and the letters are ordered
    363      1.1  mrg 		 like in ASCII.  This is true for the rest of GNU, too.  */
    364      1.1  mrg 	      if (ch == '9')
    365      1.1  mrg 		{
    366      1.1  mrg 		  wnumstr[cnt] = (wchar_t) info->spec;
    367      1.1  mrg 		  numstr[cnt] = info->spec;	/* This is tricky,
    368      1.1  mrg 		  				   think about it!  */
    369      1.1  mrg 		  break;
    370      1.1  mrg 		}
    371      1.1  mrg 	      else if (tolower (ch) < 'f')
    372      1.1  mrg 		{
    373      1.1  mrg 		  ++numstr[cnt];
    374      1.1  mrg 		  ++wnumstr[cnt];
    375      1.1  mrg 		  break;
    376      1.1  mrg 		}
    377      1.1  mrg 	      else
    378      1.1  mrg 		{
    379      1.1  mrg 		  numstr[cnt] = '0';
    380      1.1  mrg 		  wnumstr[cnt] = L_('0');
    381      1.1  mrg 		}
    382      1.1  mrg 	    }
    383      1.1  mrg 	  if (cnt < 0)
    384      1.1  mrg 	    {
    385      1.1  mrg 	      /* The mantissa so far was fff...f  Now increment the
    386      1.1  mrg 		 leading digit.  Here it is again possible that we
    387      1.1  mrg 		 get an overflow.  */
    388      1.1  mrg 	      if (leading == '9')
    389      1.1  mrg 		leading = info->spec;
    390      1.1  mrg 	      else if (tolower (leading) < 'f')
    391      1.1  mrg 		++leading;
    392      1.1  mrg 	      else
    393      1.1  mrg 		{
    394      1.1  mrg 		  leading = '1';
    395      1.1  mrg 		  if (expnegative)
    396      1.1  mrg 		    {
    397      1.1  mrg 		      exponent -= 4;
    398      1.1  mrg 		      if (exponent <= 0)
    399      1.1  mrg 			{
    400      1.1  mrg 			  exponent = -exponent;
    401      1.1  mrg 			  expnegative = 0;
    402      1.1  mrg 			}
    403      1.1  mrg 		    }
    404      1.1  mrg 		  else
    405      1.1  mrg 		    exponent += 4;
    406      1.1  mrg 		}
    407      1.1  mrg 	    }
    408      1.1  mrg 	}
    409      1.1  mrg     }
    410      1.1  mrg   else
    411      1.1  mrg     {
    412      1.1  mrg       if (precision == -1)
    413      1.1  mrg 	precision = 0;
    414      1.1  mrg       numend = numstr;
    415      1.1  mrg       wnumend = wnumstr;
    416      1.1  mrg     }
    417      1.1  mrg 
    418      1.1  mrg   /* Now we can compute the exponent string.  */
    419      1.1  mrg   expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0);
    420      1.1  mrg   wexpstr = _itowa_word (exponent,
    421      1.1  mrg 			 wexpbuf + sizeof wexpbuf / sizeof (wchar_t), 10, 0);
    422      1.1  mrg 
    423      1.1  mrg   /* Now we have all information to compute the size.  */
    424      1.1  mrg   width -= ((negative || info->showsign || info->space)
    425      1.1  mrg 	    /* Sign.  */
    426      1.1  mrg 	    + 2    + 1 + 0 + precision + 1 + 1
    427      1.1  mrg 	    /* 0x    h   .   hhh         P   ExpoSign.  */
    428      1.1  mrg 	    + ((expbuf + sizeof expbuf) - expstr));
    429      1.1  mrg 	    /* Exponent.  */
    430      1.1  mrg 
    431      1.1  mrg   /* Count the decimal point.
    432      1.1  mrg      A special case when the mantissa or the precision is zero and the `#'
    433      1.1  mrg      is not given.  In this case we must not print the decimal point.  */
    434      1.1  mrg   if (precision > 0 || info->alt)
    435      1.1  mrg     width -= wide ? 1 : strlen (decimal);
    436      1.1  mrg 
    437      1.1  mrg   if (!info->left && info->pad != '0' && width > 0)
    438      1.1  mrg     PADN (' ', width);
    439      1.1  mrg 
    440      1.1  mrg   if (negative)
    441      1.1  mrg     outchar ('-');
    442      1.1  mrg   else if (info->showsign)
    443      1.1  mrg     outchar ('+');
    444      1.1  mrg   else if (info->space)
    445      1.1  mrg     outchar (' ');
    446      1.1  mrg 
    447      1.1  mrg   outchar ('0');
    448      1.1  mrg   if ('X' - 'A' == 'x' - 'a')
    449      1.1  mrg     outchar (info->spec + ('x' - 'a'));
    450      1.1  mrg   else
    451      1.1  mrg     outchar (info->spec == 'A' ? 'X' : 'x');
    452      1.1  mrg 
    453      1.1  mrg   if (!info->left && info->pad == '0' && width > 0)
    454      1.1  mrg     PADN ('0', width);
    455      1.1  mrg 
    456      1.1  mrg   outchar (leading);
    457      1.1  mrg 
    458      1.1  mrg   if (precision > 0 || info->alt)
    459      1.1  mrg     {
    460      1.1  mrg       const wchar_t *wtmp = &decimalwc;
    461      1.1  mrg       PRINT (decimal, wtmp, wide ? 1 : strlen (decimal));
    462      1.1  mrg     }
    463      1.1  mrg 
    464      1.1  mrg   if (precision > 0)
    465      1.1  mrg     {
    466      1.1  mrg       ssize_t tofill = precision - (numend - numstr);
    467      1.1  mrg       PRINT (numstr, wnumstr, MIN (numend - numstr, precision));
    468      1.1  mrg       if (tofill > 0)
    469      1.1  mrg 	PADN ('0', tofill);
    470      1.1  mrg     }
    471      1.1  mrg 
    472      1.1  mrg   if ('P' - 'A' == 'p' - 'a')
    473      1.1  mrg     outchar (info->spec + ('p' - 'a'));
    474      1.1  mrg   else
    475      1.1  mrg     outchar (info->spec == 'A' ? 'P' : 'p');
    476      1.1  mrg 
    477      1.1  mrg   outchar (expnegative ? '-' : '+');
    478      1.1  mrg 
    479      1.1  mrg   PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr);
    480      1.1  mrg 
    481      1.1  mrg   if (info->left && info->pad != '0' && width > 0)
    482      1.1  mrg     PADN (info->pad, width);
    483      1.1  mrg 
    484                 return done;
    485               }
    486