xref: /haiku/src/system/libroot/posix/glibc/stdio-common/printf_fp.c (revision 97f11716bfaa0f385eb0e28a52bf56a5023b9e99)
15af32e75SAxel Dörfler /* Floating point output for `printf'.
25af32e75SAxel Dörfler    Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
35af32e75SAxel Dörfler    This file is part of the GNU C Library.
45af32e75SAxel Dörfler    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
55af32e75SAxel Dörfler 
65af32e75SAxel Dörfler    The GNU C Library is free software; you can redistribute it and/or
75af32e75SAxel Dörfler    modify it under the terms of the GNU Lesser General Public
85af32e75SAxel Dörfler    License as published by the Free Software Foundation; either
95af32e75SAxel Dörfler    version 2.1 of the License, or (at your option) any later version.
105af32e75SAxel Dörfler 
115af32e75SAxel Dörfler    The GNU C Library is distributed in the hope that it will be useful,
125af32e75SAxel Dörfler    but WITHOUT ANY WARRANTY; without even the implied warranty of
135af32e75SAxel Dörfler    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145af32e75SAxel Dörfler    Lesser General Public License for more details.
155af32e75SAxel Dörfler 
165af32e75SAxel Dörfler    You should have received a copy of the GNU Lesser General Public
175af32e75SAxel Dörfler    License along with the GNU C Library; if not, write to the Free
185af32e75SAxel Dörfler    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
195af32e75SAxel Dörfler    02111-1307 USA.  */
205af32e75SAxel Dörfler 
215af32e75SAxel Dörfler /* The gmp headers need some configuration frobs.  */
225af32e75SAxel Dörfler #define HAVE_ALLOCA 1
235af32e75SAxel Dörfler 
245af32e75SAxel Dörfler #ifdef USE_IN_LIBIO
255af32e75SAxel Dörfler #  include <libioP.h>
265af32e75SAxel Dörfler #else
275af32e75SAxel Dörfler #  include <stdio.h>
285af32e75SAxel Dörfler #endif
295af32e75SAxel Dörfler #include <alloca.h>
305af32e75SAxel Dörfler #include <ctype.h>
315af32e75SAxel Dörfler #include <float.h>
325af32e75SAxel Dörfler #include <gmp-mparam.h>
335af32e75SAxel Dörfler #include <gmp.h>
345af32e75SAxel Dörfler #include <stdlib/gmp-impl.h>
355af32e75SAxel Dörfler #include <stdlib/longlong.h>
365af32e75SAxel Dörfler #include <stdlib/fpioconst.h>
375af32e75SAxel Dörfler #include <locale/localeinfo.h>
385af32e75SAxel Dörfler #include <limits.h>
395af32e75SAxel Dörfler #include <math.h>
405af32e75SAxel Dörfler #include <printf.h>
415af32e75SAxel Dörfler #include <string.h>
425af32e75SAxel Dörfler #include <unistd.h>
435af32e75SAxel Dörfler #include <stdlib.h>
445af32e75SAxel Dörfler #include <wchar.h>
455af32e75SAxel Dörfler 
465af32e75SAxel Dörfler #ifndef NDEBUG
475af32e75SAxel Dörfler # define NDEBUG			/* Undefine this for debugging assertions.  */
485af32e75SAxel Dörfler #endif
495af32e75SAxel Dörfler #include <assert.h>
505af32e75SAxel Dörfler 
515af32e75SAxel Dörfler /* This defines make it possible to use the same code for GNU C library and
525af32e75SAxel Dörfler    the GNU I/O library.	 */
535af32e75SAxel Dörfler #ifdef USE_IN_LIBIO
545af32e75SAxel Dörfler # define PUT(f, s, n) _IO_sputn (f, s, n)
555af32e75SAxel Dörfler # define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n))
565af32e75SAxel Dörfler /* We use this file GNU C library and GNU I/O library.	So make
575af32e75SAxel Dörfler    names equal.	 */
585af32e75SAxel Dörfler # undef putc
595af32e75SAxel Dörfler # define putc(c, f) (wide \
605af32e75SAxel Dörfler 		      ? (int)_IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f))
615af32e75SAxel Dörfler # define size_t     _IO_size_t
625af32e75SAxel Dörfler # define FILE	     _IO_FILE
635af32e75SAxel Dörfler #else	/* ! USE_IN_LIBIO */
645af32e75SAxel Dörfler # define PUT(f, s, n) fwrite (s, 1, n, f)
655af32e75SAxel Dörfler # define PAD(f, c, n) __printf_pad (f, c, n)
665af32e75SAxel Dörfler ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c.  */
675af32e75SAxel Dörfler #endif	/* USE_IN_LIBIO */
689e419c30SAugustin Cavalier 
695af32e75SAxel Dörfler /* Macros for doing the actual output.  */
705af32e75SAxel Dörfler 
715af32e75SAxel Dörfler #define outchar(ch)							      \
725af32e75SAxel Dörfler   do									      \
735af32e75SAxel Dörfler     {									      \
745af32e75SAxel Dörfler       register const int outc = (ch);					      \
755af32e75SAxel Dörfler       if (putc (outc, fp) == EOF)					      \
765af32e75SAxel Dörfler 	return -1;							      \
775af32e75SAxel Dörfler       ++done;								      \
785af32e75SAxel Dörfler     } while (0)
795af32e75SAxel Dörfler 
805af32e75SAxel Dörfler #define PRINT(ptr, wptr, len)						      \
815af32e75SAxel Dörfler   do									      \
825af32e75SAxel Dörfler     {									      \
835af32e75SAxel Dörfler       register size_t outlen = (len);					      \
845af32e75SAxel Dörfler       if (len > 20)							      \
855af32e75SAxel Dörfler 	{								      \
865af32e75SAxel Dörfler 	  if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
875af32e75SAxel Dörfler 	    return -1;							      \
885af32e75SAxel Dörfler 	  ptr += outlen;						      \
895af32e75SAxel Dörfler 	  done += outlen;						      \
905af32e75SAxel Dörfler 	}								      \
915af32e75SAxel Dörfler       else								      \
925af32e75SAxel Dörfler 	{								      \
935af32e75SAxel Dörfler 	  if (wide)							      \
945af32e75SAxel Dörfler 	    while (outlen-- > 0)					      \
955af32e75SAxel Dörfler 	      outchar (*wptr++);					      \
965af32e75SAxel Dörfler 	  else								      \
975af32e75SAxel Dörfler 	    while (outlen-- > 0)					      \
985af32e75SAxel Dörfler 	      outchar (*ptr++);						      \
995af32e75SAxel Dörfler 	}								      \
1005af32e75SAxel Dörfler     } while (0)
1015af32e75SAxel Dörfler 
1025af32e75SAxel Dörfler #define PADN(ch, len)							      \
1035af32e75SAxel Dörfler   do									      \
1045af32e75SAxel Dörfler     {									      \
1055af32e75SAxel Dörfler       if (PAD (fp, ch, len) != len)					      \
1065af32e75SAxel Dörfler 	return -1;							      \
1075af32e75SAxel Dörfler       done += len;							      \
1085af32e75SAxel Dörfler     }									      \
1095af32e75SAxel Dörfler   while (0)
1109e419c30SAugustin Cavalier 
1115af32e75SAxel Dörfler /* We use the GNU MP library to handle large numbers.
1125af32e75SAxel Dörfler 
1135af32e75SAxel Dörfler    An MP variable occupies a varying number of entries in its array.  We keep
1145af32e75SAxel Dörfler    track of this number for efficiency reasons.  Otherwise we would always
1155af32e75SAxel Dörfler    have to process the whole array.  */
1165af32e75SAxel Dörfler #define MPN_VAR(name) mp_limb_t *name; mp_size_t name##size
1175af32e75SAxel Dörfler 
1185af32e75SAxel Dörfler #define MPN_ASSIGN(dst,src)						      \
1195af32e75SAxel Dörfler   memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb_t))
1205af32e75SAxel Dörfler #define MPN_GE(u,v) \
1215af32e75SAxel Dörfler   (u##size > v##size || (u##size == v##size && __mpn_cmp (u, v, u##size) >= 0))
1225af32e75SAxel Dörfler 
1235af32e75SAxel Dörfler extern mp_size_t __mpn_extract_double (mp_ptr res_ptr, mp_size_t size,
1245af32e75SAxel Dörfler 				       int *expt, int *is_neg,
1255af32e75SAxel Dörfler 				       double value);
1265af32e75SAxel Dörfler extern mp_size_t __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
1275af32e75SAxel Dörfler 					    int *expt, int *is_neg,
1285af32e75SAxel Dörfler 					    long double value);
1295af32e75SAxel Dörfler extern unsigned int __guess_grouping (unsigned int intdig_max,
1305af32e75SAxel Dörfler 				      const char *grouping);
1315af32e75SAxel Dörfler 
1325af32e75SAxel Dörfler 
1335af32e75SAxel Dörfler static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
1345af32e75SAxel Dörfler 			      unsigned int intdig_no, const char *grouping,
1355af32e75SAxel Dörfler 			      wchar_t thousands_sep, int ngroups)
1365af32e75SAxel Dörfler      internal_function;
1375af32e75SAxel Dörfler 
1385af32e75SAxel Dörfler 
1395af32e75SAxel Dörfler int
__printf_fp(FILE * fp,const struct printf_info * info,const void * const * args)1405af32e75SAxel Dörfler __printf_fp (FILE *fp,
1415af32e75SAxel Dörfler 	     const struct printf_info *info,
1425af32e75SAxel Dörfler 	     const void *const *args)
1435af32e75SAxel Dörfler {
1445af32e75SAxel Dörfler   /* The floating-point value to output.  */
1455af32e75SAxel Dörfler   union
1465af32e75SAxel Dörfler     {
1475af32e75SAxel Dörfler       double dbl;
1485af32e75SAxel Dörfler       __long_double_t ldbl;
1495af32e75SAxel Dörfler     }
1505af32e75SAxel Dörfler   fpnum;
1515af32e75SAxel Dörfler 
1525af32e75SAxel Dörfler   /* Locale-dependent representation of decimal point.	*/
1535af32e75SAxel Dörfler   const char *decimal;
1545af32e75SAxel Dörfler   wchar_t decimalwc;
1555af32e75SAxel Dörfler 
1565af32e75SAxel Dörfler   /* Locale-dependent thousands separator and grouping specification.  */
1575af32e75SAxel Dörfler   const char *thousands_sep = NULL;
1585af32e75SAxel Dörfler   wchar_t thousands_sepwc = 0;
1595af32e75SAxel Dörfler   const char *grouping;
1605af32e75SAxel Dörfler 
1615af32e75SAxel Dörfler   /* "NaN" or "Inf" for the special cases.  */
1625af32e75SAxel Dörfler   const char *special = NULL;
1635af32e75SAxel Dörfler   const wchar_t *wspecial = NULL;
1645af32e75SAxel Dörfler 
1655af32e75SAxel Dörfler   /* We need just a few limbs for the input before shifting to the right
1665af32e75SAxel Dörfler      position.	*/
1675af32e75SAxel Dörfler   mp_limb_t fp_input[(LDBL_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB];
1685af32e75SAxel Dörfler   /* We need to shift the contents of fp_input by this amount of bits.	*/
1695af32e75SAxel Dörfler   int to_shift = 0;
1705af32e75SAxel Dörfler 
1715af32e75SAxel Dörfler   /* The fraction of the floting-point value in question  */
1725af32e75SAxel Dörfler   MPN_VAR(frac);
1735af32e75SAxel Dörfler   /* and the exponent.	*/
1745af32e75SAxel Dörfler   int exponent;
1755af32e75SAxel Dörfler   /* Sign of the exponent.  */
1765af32e75SAxel Dörfler   int expsign = 0;
1775af32e75SAxel Dörfler   /* Sign of float number.  */
1785af32e75SAxel Dörfler   int is_neg = 0;
1795af32e75SAxel Dörfler 
1805af32e75SAxel Dörfler   /* Scaling factor.  */
1815af32e75SAxel Dörfler   MPN_VAR(scale);
1825af32e75SAxel Dörfler 
1835af32e75SAxel Dörfler   /* Temporary bignum value.  */
1845af32e75SAxel Dörfler   MPN_VAR(tmp);
1855af32e75SAxel Dörfler 
1865af32e75SAxel Dörfler   /* Digit which is result of last hack_digit() call.  */
1875af32e75SAxel Dörfler   wchar_t digit;
1885af32e75SAxel Dörfler 
189*ae7395c8STrung Nguyen   /* The type of output format that will be used: 'e'/'E' or 'f'/'F'.  */
1905af32e75SAxel Dörfler   int type;
1915af32e75SAxel Dörfler 
1925af32e75SAxel Dörfler   /* Counter for number of written characters.	*/
1935af32e75SAxel Dörfler   int done = 0;
1945af32e75SAxel Dörfler 
1955af32e75SAxel Dörfler   /* General helper (carry limb).  */
1965af32e75SAxel Dörfler   mp_limb_t cy;
1975af32e75SAxel Dörfler 
1985af32e75SAxel Dörfler   /* Nonzero if this is output on a wide character stream.  */
1995af32e75SAxel Dörfler   int wide = info->wide;
2005af32e75SAxel Dörfler 
20138fee4c3SJonathan Schleifer   wchar_t hack_digit_ret;
20238fee4c3SJonathan Schleifer   int hack_digit_callee;
2035af32e75SAxel Dörfler 
20438fee4c3SJonathan Schleifer   while (0)
2055af32e75SAxel Dörfler     {
2065af32e75SAxel Dörfler       mp_limb_t hi;
2075af32e75SAxel Dörfler 
20838fee4c3SJonathan Schleifer hack_digit:
209*ae7395c8STrung Nguyen       if (expsign != 0 && _tolower (type) == 'f' && exponent-- > 0)
2105af32e75SAxel Dörfler 	hi = 0;
2115af32e75SAxel Dörfler       else if (scalesize == 0)
2125af32e75SAxel Dörfler 	{
2135af32e75SAxel Dörfler 	  hi = frac[fracsize - 1];
2145af32e75SAxel Dörfler 	  cy = __mpn_mul_1 (frac, frac, fracsize - 1, 10);
2155af32e75SAxel Dörfler 	  frac[fracsize - 1] = cy;
2165af32e75SAxel Dörfler 	}
2175af32e75SAxel Dörfler       else
2185af32e75SAxel Dörfler 	{
2195af32e75SAxel Dörfler 	  if (fracsize < scalesize)
2205af32e75SAxel Dörfler 	    hi = 0;
2215af32e75SAxel Dörfler 	  else
2225af32e75SAxel Dörfler 	    {
2235af32e75SAxel Dörfler 	      hi = mpn_divmod (tmp, frac, fracsize, scale, scalesize);
2245af32e75SAxel Dörfler 	      tmp[fracsize - scalesize] = hi;
2255af32e75SAxel Dörfler 	      hi = tmp[0];
2265af32e75SAxel Dörfler 
2275af32e75SAxel Dörfler 	      fracsize = scalesize;
2285af32e75SAxel Dörfler 	      while (fracsize != 0 && frac[fracsize - 1] == 0)
2295af32e75SAxel Dörfler 		--fracsize;
2305af32e75SAxel Dörfler 	      if (fracsize == 0)
2315af32e75SAxel Dörfler 		{
2325af32e75SAxel Dörfler 		  /* We're not prepared for an mpn variable with zero
2335af32e75SAxel Dörfler 		     limbs.  */
2345af32e75SAxel Dörfler 		  fracsize = 1;
23538fee4c3SJonathan Schleifer 		  hack_digit_ret = L'0' + hi;
23638fee4c3SJonathan Schleifer 		  goto hack_digit_end;
2375af32e75SAxel Dörfler 		}
2385af32e75SAxel Dörfler 	    }
2395af32e75SAxel Dörfler 
2405af32e75SAxel Dörfler 	  cy = __mpn_mul_1 (frac, frac, fracsize, 10);
2415af32e75SAxel Dörfler 	  if (cy != 0)
2425af32e75SAxel Dörfler 	    frac[fracsize++] = cy;
2435af32e75SAxel Dörfler 	}
2445af32e75SAxel Dörfler 
24538fee4c3SJonathan Schleifer       hack_digit_ret = L'0' + hi;
24638fee4c3SJonathan Schleifer hack_digit_end:
24738fee4c3SJonathan Schleifer       switch (hack_digit_callee)
24838fee4c3SJonathan Schleifer         {
24938fee4c3SJonathan Schleifer 	  case 1: goto hack_digit_callee1;
25038fee4c3SJonathan Schleifer 	  case 2: goto hack_digit_callee2;
25138fee4c3SJonathan Schleifer 	  case 3: goto hack_digit_callee3;
25238fee4c3SJonathan Schleifer 	  default: abort();
25338fee4c3SJonathan Schleifer 	}
2545af32e75SAxel Dörfler     }
2555af32e75SAxel Dörfler 
2565af32e75SAxel Dörfler 
2575af32e75SAxel Dörfler   /* Figure out the decimal point character.  */
2585af32e75SAxel Dörfler   if (info->extra == 0)
2595af32e75SAxel Dörfler     {
2605af32e75SAxel Dörfler       decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
2615af32e75SAxel Dörfler       decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
2625af32e75SAxel Dörfler     }
2635af32e75SAxel Dörfler   else
2645af32e75SAxel Dörfler     {
2655af32e75SAxel Dörfler       decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
2665af32e75SAxel Dörfler       if (*decimal == '\0')
2675af32e75SAxel Dörfler 	decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
2685af32e75SAxel Dörfler       decimalwc = _NL_CURRENT_WORD (LC_MONETARY,
2695af32e75SAxel Dörfler 				    _NL_MONETARY_DECIMAL_POINT_WC);
2705af32e75SAxel Dörfler       if (decimalwc == L'\0')
2715af32e75SAxel Dörfler 	decimalwc = _NL_CURRENT_WORD (LC_NUMERIC,
2725af32e75SAxel Dörfler 				      _NL_NUMERIC_DECIMAL_POINT_WC);
2735af32e75SAxel Dörfler     }
2745af32e75SAxel Dörfler   /* The decimal point character must not be zero.  */
2755af32e75SAxel Dörfler   assert (*decimal != '\0');
2765af32e75SAxel Dörfler   assert (decimalwc != L'\0');
2775af32e75SAxel Dörfler 
2785af32e75SAxel Dörfler   if (info->group)
2795af32e75SAxel Dörfler     {
2805af32e75SAxel Dörfler       if (info->extra == 0)
2815af32e75SAxel Dörfler 	grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
2825af32e75SAxel Dörfler       else
2835af32e75SAxel Dörfler 	grouping = _NL_CURRENT (LC_MONETARY, MON_GROUPING);
2845af32e75SAxel Dörfler 
2855af32e75SAxel Dörfler       if (*grouping <= 0 || *grouping == CHAR_MAX)
2865af32e75SAxel Dörfler 	grouping = NULL;
2875af32e75SAxel Dörfler       else
2885af32e75SAxel Dörfler 	{
2895af32e75SAxel Dörfler 	  /* Figure out the thousands separator character.  */
2905af32e75SAxel Dörfler 	  if (wide)
2915af32e75SAxel Dörfler 	    {
2925af32e75SAxel Dörfler 	      if (info->extra == 0)
2935af32e75SAxel Dörfler 		thousands_sepwc =
2945af32e75SAxel Dörfler 		  _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
2955af32e75SAxel Dörfler 	      else
2965af32e75SAxel Dörfler 		thousands_sepwc =
2975af32e75SAxel Dörfler 		  _NL_CURRENT_WORD (LC_MONETARY,
2985af32e75SAxel Dörfler 				    _NL_MONETARY_THOUSANDS_SEP_WC);
2995af32e75SAxel Dörfler 	    }
3005af32e75SAxel Dörfler 	  else
3015af32e75SAxel Dörfler 	    {
3025af32e75SAxel Dörfler 	      if (info->extra == 0)
3035af32e75SAxel Dörfler 		thousands_sep = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
3045af32e75SAxel Dörfler 	      else
3055af32e75SAxel Dörfler 		thousands_sep = _NL_CURRENT (LC_MONETARY, MON_THOUSANDS_SEP);
3065af32e75SAxel Dörfler 	    }
3075af32e75SAxel Dörfler 
3085af32e75SAxel Dörfler 	  if ((wide && thousands_sepwc == L'\0')
3095af32e75SAxel Dörfler 	      || (! wide && *thousands_sep == '\0'))
3105af32e75SAxel Dörfler 	    grouping = NULL;
3115af32e75SAxel Dörfler 	  else if (thousands_sepwc == L'\0')
3125af32e75SAxel Dörfler 	    /* If we are printing multibyte characters and there is a
3135af32e75SAxel Dörfler 	       multibyte representation for the thousands separator,
3145af32e75SAxel Dörfler 	       we must ensure the wide character thousands separator
3155af32e75SAxel Dörfler 	       is available, even if it is fake.  */
3165af32e75SAxel Dörfler 	    thousands_sepwc = 0xfffffffe;
3175af32e75SAxel Dörfler 	}
3185af32e75SAxel Dörfler     }
3195af32e75SAxel Dörfler   else
3205af32e75SAxel Dörfler     grouping = NULL;
3215af32e75SAxel Dörfler 
3225af32e75SAxel Dörfler   /* Fetch the argument value.	*/
3235af32e75SAxel Dörfler #ifndef __NO_LONG_DOUBLE_MATH
3245af32e75SAxel Dörfler   if (info->is_long_double && sizeof (long double) > sizeof (double))
3255af32e75SAxel Dörfler     {
3265af32e75SAxel Dörfler       fpnum.ldbl = *(const long double *) args[0];
3275af32e75SAxel Dörfler 
3285af32e75SAxel Dörfler       /* Check for special values: not a number or infinity.  */
3299e419c30SAugustin Cavalier       if (isnan (fpnum.ldbl))
3305af32e75SAxel Dörfler 	{
3315af32e75SAxel Dörfler 	  if (isupper (info->spec))
3325af32e75SAxel Dörfler 	    {
3335af32e75SAxel Dörfler 	      special = "NAN";
3345af32e75SAxel Dörfler 	      wspecial = L"NAN";
3355af32e75SAxel Dörfler 	    }
3365af32e75SAxel Dörfler 	    else
3375af32e75SAxel Dörfler 	      {
3385af32e75SAxel Dörfler 		special = "nan";
3395af32e75SAxel Dörfler 		wspecial = L"nan";
3405af32e75SAxel Dörfler 	      }
3415af32e75SAxel Dörfler 	  is_neg = 0;
3425af32e75SAxel Dörfler 	}
3439e419c30SAugustin Cavalier       else if (isinf (fpnum.ldbl))
3445af32e75SAxel Dörfler 	{
3455af32e75SAxel Dörfler 	  if (isupper (info->spec))
3465af32e75SAxel Dörfler 	    {
3475af32e75SAxel Dörfler 	      special = "INF";
3485af32e75SAxel Dörfler 	      wspecial = L"INF";
3495af32e75SAxel Dörfler 	    }
3505af32e75SAxel Dörfler 	  else
3515af32e75SAxel Dörfler 	    {
3525af32e75SAxel Dörfler 	      special = "inf";
3535af32e75SAxel Dörfler 	      wspecial = L"inf";
3545af32e75SAxel Dörfler 	    }
3555af32e75SAxel Dörfler 	  is_neg = fpnum.ldbl < 0;
3565af32e75SAxel Dörfler 	}
3575af32e75SAxel Dörfler       else
3585af32e75SAxel Dörfler 	{
3595af32e75SAxel Dörfler 	  fracsize = __mpn_extract_long_double (fp_input,
3605af32e75SAxel Dörfler 						(sizeof (fp_input) /
3615af32e75SAxel Dörfler 						 sizeof (fp_input[0])),
3625af32e75SAxel Dörfler 						&exponent, &is_neg,
3635af32e75SAxel Dörfler 						fpnum.ldbl);
3645af32e75SAxel Dörfler 	  to_shift = 1 + fracsize * BITS_PER_MP_LIMB - LDBL_MANT_DIG;
3655af32e75SAxel Dörfler 	}
3665af32e75SAxel Dörfler     }
3675af32e75SAxel Dörfler   else
3685af32e75SAxel Dörfler #endif	/* no long double */
3695af32e75SAxel Dörfler     {
3705af32e75SAxel Dörfler       fpnum.dbl = *(const double *) args[0];
3715af32e75SAxel Dörfler 
3725af32e75SAxel Dörfler       /* Check for special values: not a number or infinity.  */
3739e419c30SAugustin Cavalier       if (isnan (fpnum.dbl))
3745af32e75SAxel Dörfler 	{
3755af32e75SAxel Dörfler 	  if (isupper (info->spec))
3765af32e75SAxel Dörfler 	    {
3775af32e75SAxel Dörfler 	      special = "NAN";
3785af32e75SAxel Dörfler 	      wspecial = L"NAN";
3795af32e75SAxel Dörfler 	    }
3805af32e75SAxel Dörfler 	  else
3815af32e75SAxel Dörfler 	    {
3825af32e75SAxel Dörfler 	      special = "nan";
3835af32e75SAxel Dörfler 	      wspecial = L"nan";
3845af32e75SAxel Dörfler 	    }
3855af32e75SAxel Dörfler 	  is_neg = 0;
3865af32e75SAxel Dörfler 	}
3879e419c30SAugustin Cavalier       else if (isinf (fpnum.dbl))
3885af32e75SAxel Dörfler 	{
3895af32e75SAxel Dörfler 	  if (isupper (info->spec))
3905af32e75SAxel Dörfler 	    {
3915af32e75SAxel Dörfler 	      special = "INF";
3925af32e75SAxel Dörfler 	      wspecial = L"INF";
3935af32e75SAxel Dörfler 	    }
3945af32e75SAxel Dörfler 	  else
3955af32e75SAxel Dörfler 	    {
3965af32e75SAxel Dörfler 	      special = "inf";
3975af32e75SAxel Dörfler 	      wspecial = L"inf";
3985af32e75SAxel Dörfler 	    }
3995af32e75SAxel Dörfler 	  is_neg = fpnum.dbl < 0;
4005af32e75SAxel Dörfler 	}
4015af32e75SAxel Dörfler       else
4025af32e75SAxel Dörfler 	{
4035af32e75SAxel Dörfler 	  fracsize = __mpn_extract_double (fp_input,
4045af32e75SAxel Dörfler 					   (sizeof (fp_input)
4055af32e75SAxel Dörfler 					    / sizeof (fp_input[0])),
4065af32e75SAxel Dörfler 					   &exponent, &is_neg, fpnum.dbl);
4075af32e75SAxel Dörfler 	  to_shift = 1 + fracsize * BITS_PER_MP_LIMB - DBL_MANT_DIG;
4085af32e75SAxel Dörfler 	}
4095af32e75SAxel Dörfler     }
4105af32e75SAxel Dörfler 
4115af32e75SAxel Dörfler   if (special)
4125af32e75SAxel Dörfler     {
4135af32e75SAxel Dörfler       int width = info->width;
4145af32e75SAxel Dörfler 
4155af32e75SAxel Dörfler       if (is_neg || info->showsign || info->space)
4165af32e75SAxel Dörfler 	--width;
4175af32e75SAxel Dörfler       width -= 3;
4185af32e75SAxel Dörfler 
4195af32e75SAxel Dörfler       if (!info->left && width > 0)
4205af32e75SAxel Dörfler 	PADN (' ', width);
4215af32e75SAxel Dörfler 
4225af32e75SAxel Dörfler       if (is_neg)
4235af32e75SAxel Dörfler 	outchar ('-');
4245af32e75SAxel Dörfler       else if (info->showsign)
4255af32e75SAxel Dörfler 	outchar ('+');
4265af32e75SAxel Dörfler       else if (info->space)
4275af32e75SAxel Dörfler 	outchar (' ');
4285af32e75SAxel Dörfler 
4295af32e75SAxel Dörfler       PRINT (special, wspecial, 3);
4305af32e75SAxel Dörfler 
4315af32e75SAxel Dörfler       if (info->left && width > 0)
4325af32e75SAxel Dörfler 	PADN (' ', width);
4335af32e75SAxel Dörfler 
4345af32e75SAxel Dörfler       return done;
4355af32e75SAxel Dörfler     }
4365af32e75SAxel Dörfler 
4375af32e75SAxel Dörfler 
4385af32e75SAxel Dörfler   /* We need three multiprecision variables.  Now that we have the exponent
4395af32e75SAxel Dörfler      of the number we can allocate the needed memory.  It would be more
4405af32e75SAxel Dörfler      efficient to use variables of the fixed maximum size but because this
4415af32e75SAxel Dörfler      would be really big it could lead to memory problems.  */
4425af32e75SAxel Dörfler   {
4435af32e75SAxel Dörfler     mp_size_t bignum_size = ((ABS (exponent) + BITS_PER_MP_LIMB - 1)
4445af32e75SAxel Dörfler 			     / BITS_PER_MP_LIMB + 4) * sizeof (mp_limb_t);
4455af32e75SAxel Dörfler     frac = (mp_limb_t *) alloca (bignum_size);
4465af32e75SAxel Dörfler     tmp = (mp_limb_t *) alloca (bignum_size);
4475af32e75SAxel Dörfler     scale = (mp_limb_t *) alloca (bignum_size);
4485af32e75SAxel Dörfler   }
4495af32e75SAxel Dörfler 
4505af32e75SAxel Dörfler   /* We now have to distinguish between numbers with positive and negative
4515af32e75SAxel Dörfler      exponents because the method used for the one is not applicable/efficient
4525af32e75SAxel Dörfler      for the other.  */
4535af32e75SAxel Dörfler   scalesize = 0;
4545af32e75SAxel Dörfler   if (exponent > 2)
4555af32e75SAxel Dörfler     {
4565af32e75SAxel Dörfler       /* |FP| >= 8.0.  */
4575af32e75SAxel Dörfler       int scaleexpo = 0;
4585af32e75SAxel Dörfler       int explog = LDBL_MAX_10_EXP_LOG;
4595af32e75SAxel Dörfler       int exp10 = 0;
4605af32e75SAxel Dörfler       const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
4615af32e75SAxel Dörfler       int cnt_h, cnt_l, i;
4625af32e75SAxel Dörfler 
4635af32e75SAxel Dörfler       if ((exponent + to_shift) % BITS_PER_MP_LIMB == 0)
4645af32e75SAxel Dörfler 	{
4655af32e75SAxel Dörfler 	  MPN_COPY_DECR (frac + (exponent + to_shift) / BITS_PER_MP_LIMB,
4665af32e75SAxel Dörfler 			 fp_input, fracsize);
4675af32e75SAxel Dörfler 	  fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB;
4685af32e75SAxel Dörfler 	}
4695af32e75SAxel Dörfler       else
4705af32e75SAxel Dörfler 	{
4715af32e75SAxel Dörfler 	  cy = __mpn_lshift (frac + (exponent + to_shift) / BITS_PER_MP_LIMB,
4725af32e75SAxel Dörfler 			     fp_input, fracsize,
4735af32e75SAxel Dörfler 			     (exponent + to_shift) % BITS_PER_MP_LIMB);
4745af32e75SAxel Dörfler 	  fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB;
4755af32e75SAxel Dörfler 	  if (cy)
4765af32e75SAxel Dörfler 	    frac[fracsize++] = cy;
4775af32e75SAxel Dörfler 	}
4785af32e75SAxel Dörfler       MPN_ZERO (frac, (exponent + to_shift) / BITS_PER_MP_LIMB);
4795af32e75SAxel Dörfler 
4805af32e75SAxel Dörfler       assert (powers > &_fpioconst_pow10[0]);
4815af32e75SAxel Dörfler       do
4825af32e75SAxel Dörfler 	{
4835af32e75SAxel Dörfler 	  --powers;
4845af32e75SAxel Dörfler 
4855af32e75SAxel Dörfler 	  /* The number of the product of two binary numbers with n and m
4865af32e75SAxel Dörfler 	     bits respectively has m+n or m+n-1 bits.	*/
4875af32e75SAxel Dörfler 	  if (exponent >= scaleexpo + powers->p_expo - 1)
4885af32e75SAxel Dörfler 	    {
4895af32e75SAxel Dörfler 	      if (scalesize == 0)
4905af32e75SAxel Dörfler 		{
4915af32e75SAxel Dörfler #ifndef __NO_LONG_DOUBLE_MATH
4925af32e75SAxel Dörfler 		  if (LDBL_MANT_DIG > _FPIO_CONST_OFFSET * BITS_PER_MP_LIMB
4935af32e75SAxel Dörfler 		      && info->is_long_double)
4945af32e75SAxel Dörfler 		    {
4955af32e75SAxel Dörfler #define _FPIO_CONST_SHIFT \
4965af32e75SAxel Dörfler   (((LDBL_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB) \
4975af32e75SAxel Dörfler    - _FPIO_CONST_OFFSET)
4985af32e75SAxel Dörfler 		      /* 64bit const offset is not enough for
4995af32e75SAxel Dörfler 			 IEEE quad long double.  */
5005af32e75SAxel Dörfler 		      tmpsize = powers->arraysize + _FPIO_CONST_SHIFT;
5015af32e75SAxel Dörfler 		      memcpy (tmp + _FPIO_CONST_SHIFT,
5025af32e75SAxel Dörfler 			      &__tens[powers->arrayoff],
5035af32e75SAxel Dörfler 			      tmpsize * sizeof (mp_limb_t));
5045af32e75SAxel Dörfler 		      MPN_ZERO (tmp, _FPIO_CONST_SHIFT);
5055af32e75SAxel Dörfler 		    }
5065af32e75SAxel Dörfler 		  else
5075af32e75SAxel Dörfler #endif
5085af32e75SAxel Dörfler 		    {
5095af32e75SAxel Dörfler 		      tmpsize = powers->arraysize;
5105af32e75SAxel Dörfler 		      memcpy (tmp, &__tens[powers->arrayoff],
5115af32e75SAxel Dörfler 			      tmpsize * sizeof (mp_limb_t));
5125af32e75SAxel Dörfler 		    }
5135af32e75SAxel Dörfler 		}
5145af32e75SAxel Dörfler 	      else
5155af32e75SAxel Dörfler 		{
5165af32e75SAxel Dörfler 		  cy = __mpn_mul (tmp, scale, scalesize,
5175af32e75SAxel Dörfler 				  &__tens[powers->arrayoff
5185af32e75SAxel Dörfler 					 + _FPIO_CONST_OFFSET],
5195af32e75SAxel Dörfler 				  powers->arraysize - _FPIO_CONST_OFFSET);
5205af32e75SAxel Dörfler 		  tmpsize = scalesize + powers->arraysize - _FPIO_CONST_OFFSET;
5215af32e75SAxel Dörfler 		  if (cy == 0)
5225af32e75SAxel Dörfler 		    --tmpsize;
5235af32e75SAxel Dörfler 		}
5245af32e75SAxel Dörfler 
5255af32e75SAxel Dörfler 	      if (MPN_GE (frac, tmp))
5265af32e75SAxel Dörfler 		{
5275af32e75SAxel Dörfler 		  int cnt;
5285af32e75SAxel Dörfler 		  MPN_ASSIGN (scale, tmp);
5295af32e75SAxel Dörfler 		  count_leading_zeros (cnt, scale[scalesize - 1]);
5305af32e75SAxel Dörfler 		  scaleexpo = (scalesize - 2) * BITS_PER_MP_LIMB - cnt - 1;
5315af32e75SAxel Dörfler 		  exp10 |= 1 << explog;
5325af32e75SAxel Dörfler 		}
5335af32e75SAxel Dörfler 	    }
5345af32e75SAxel Dörfler 	  --explog;
5355af32e75SAxel Dörfler 	}
5365af32e75SAxel Dörfler       while (powers > &_fpioconst_pow10[0]);
5375af32e75SAxel Dörfler       exponent = exp10;
5385af32e75SAxel Dörfler 
5395af32e75SAxel Dörfler       /* Optimize number representations.  We want to represent the numbers
5405af32e75SAxel Dörfler 	 with the lowest number of bytes possible without losing any
5415af32e75SAxel Dörfler 	 bytes. Also the highest bit in the scaling factor has to be set
5425af32e75SAxel Dörfler 	 (this is a requirement of the MPN division routines).  */
5435af32e75SAxel Dörfler       if (scalesize > 0)
5445af32e75SAxel Dörfler 	{
5455af32e75SAxel Dörfler 	  /* Determine minimum number of zero bits at the end of
5465af32e75SAxel Dörfler 	     both numbers.  */
5475af32e75SAxel Dörfler 	  for (i = 0; scale[i] == 0 && frac[i] == 0; i++)
5485af32e75SAxel Dörfler 	    ;
5495af32e75SAxel Dörfler 
5505af32e75SAxel Dörfler 	  /* Determine number of bits the scaling factor is misplaced.	*/
5515af32e75SAxel Dörfler 	  count_leading_zeros (cnt_h, scale[scalesize - 1]);
5525af32e75SAxel Dörfler 
5535af32e75SAxel Dörfler 	  if (cnt_h == 0)
5545af32e75SAxel Dörfler 	    {
5555af32e75SAxel Dörfler 	      /* The highest bit of the scaling factor is already set.	So
5565af32e75SAxel Dörfler 		 we only have to remove the trailing empty limbs.  */
5575af32e75SAxel Dörfler 	      if (i > 0)
5585af32e75SAxel Dörfler 		{
5595af32e75SAxel Dörfler 		  MPN_COPY_INCR (scale, scale + i, scalesize - i);
5605af32e75SAxel Dörfler 		  scalesize -= i;
5615af32e75SAxel Dörfler 		  MPN_COPY_INCR (frac, frac + i, fracsize - i);
5625af32e75SAxel Dörfler 		  fracsize -= i;
5635af32e75SAxel Dörfler 		}
5645af32e75SAxel Dörfler 	    }
5655af32e75SAxel Dörfler 	  else
5665af32e75SAxel Dörfler 	    {
5675af32e75SAxel Dörfler 	      if (scale[i] != 0)
5685af32e75SAxel Dörfler 		{
5695af32e75SAxel Dörfler 		  count_trailing_zeros (cnt_l, scale[i]);
5705af32e75SAxel Dörfler 		  if (frac[i] != 0)
5715af32e75SAxel Dörfler 		    {
5725af32e75SAxel Dörfler 		      int cnt_l2;
5735af32e75SAxel Dörfler 		      count_trailing_zeros (cnt_l2, frac[i]);
5745af32e75SAxel Dörfler 		      if (cnt_l2 < cnt_l)
5755af32e75SAxel Dörfler 			cnt_l = cnt_l2;
5765af32e75SAxel Dörfler 		    }
5775af32e75SAxel Dörfler 		}
5785af32e75SAxel Dörfler 	      else
5795af32e75SAxel Dörfler 		count_trailing_zeros (cnt_l, frac[i]);
5805af32e75SAxel Dörfler 
5815af32e75SAxel Dörfler 	      /* Now shift the numbers to their optimal position.  */
5825af32e75SAxel Dörfler 	      if (i == 0 && BITS_PER_MP_LIMB - cnt_h > cnt_l)
5835af32e75SAxel Dörfler 		{
5845af32e75SAxel Dörfler 		  /* We cannot save any memory.	 So just roll both numbers
5855af32e75SAxel Dörfler 		     so that the scaling factor has its highest bit set.  */
5865af32e75SAxel Dörfler 
5875af32e75SAxel Dörfler 		  (void) __mpn_lshift (scale, scale, scalesize, cnt_h);
5885af32e75SAxel Dörfler 		  cy = __mpn_lshift (frac, frac, fracsize, cnt_h);
5895af32e75SAxel Dörfler 		  if (cy != 0)
5905af32e75SAxel Dörfler 		    frac[fracsize++] = cy;
5915af32e75SAxel Dörfler 		}
5925af32e75SAxel Dörfler 	      else if (BITS_PER_MP_LIMB - cnt_h <= cnt_l)
5935af32e75SAxel Dörfler 		{
5945af32e75SAxel Dörfler 		  /* We can save memory by removing the trailing zero limbs
5955af32e75SAxel Dörfler 		     and by packing the non-zero limbs which gain another
5965af32e75SAxel Dörfler 		     free one. */
5975af32e75SAxel Dörfler 
5985af32e75SAxel Dörfler 		  (void) __mpn_rshift (scale, scale + i, scalesize - i,
5995af32e75SAxel Dörfler 				       BITS_PER_MP_LIMB - cnt_h);
6005af32e75SAxel Dörfler 		  scalesize -= i + 1;
6015af32e75SAxel Dörfler 		  (void) __mpn_rshift (frac, frac + i, fracsize - i,
6025af32e75SAxel Dörfler 				       BITS_PER_MP_LIMB - cnt_h);
6035af32e75SAxel Dörfler 		  fracsize -= frac[fracsize - i - 1] == 0 ? i + 1 : i;
6045af32e75SAxel Dörfler 		}
6055af32e75SAxel Dörfler 	      else
6065af32e75SAxel Dörfler 		{
6075af32e75SAxel Dörfler 		  /* We can only save the memory of the limbs which are zero.
6085af32e75SAxel Dörfler 		     The non-zero parts occupy the same number of limbs.  */
6095af32e75SAxel Dörfler 
6105af32e75SAxel Dörfler 		  (void) __mpn_rshift (scale, scale + (i - 1),
6115af32e75SAxel Dörfler 				       scalesize - (i - 1),
6125af32e75SAxel Dörfler 				       BITS_PER_MP_LIMB - cnt_h);
6135af32e75SAxel Dörfler 		  scalesize -= i;
6145af32e75SAxel Dörfler 		  (void) __mpn_rshift (frac, frac + (i - 1),
6155af32e75SAxel Dörfler 				       fracsize - (i - 1),
6165af32e75SAxel Dörfler 				       BITS_PER_MP_LIMB - cnt_h);
6175af32e75SAxel Dörfler 		  fracsize -= frac[fracsize - (i - 1) - 1] == 0 ? i : i - 1;
6185af32e75SAxel Dörfler 		}
6195af32e75SAxel Dörfler 	    }
6205af32e75SAxel Dörfler 	}
6215af32e75SAxel Dörfler     }
6225af32e75SAxel Dörfler   else if (exponent < 0)
6235af32e75SAxel Dörfler     {
6245af32e75SAxel Dörfler       /* |FP| < 1.0.  */
6255af32e75SAxel Dörfler       int exp10 = 0;
6265af32e75SAxel Dörfler       int explog = LDBL_MAX_10_EXP_LOG;
6275af32e75SAxel Dörfler       const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
6285af32e75SAxel Dörfler       mp_size_t used_limbs = fracsize - 1;
6295af32e75SAxel Dörfler 
6305af32e75SAxel Dörfler       /* Now shift the input value to its right place.	*/
6315af32e75SAxel Dörfler       cy = __mpn_lshift (frac, fp_input, fracsize, to_shift);
6325af32e75SAxel Dörfler       frac[fracsize++] = cy;
6335af32e75SAxel Dörfler       assert (cy == 1 || (frac[fracsize - 2] == 0 && frac[0] == 0));
6345af32e75SAxel Dörfler 
6355af32e75SAxel Dörfler       expsign = 1;
6365af32e75SAxel Dörfler       exponent = -exponent;
6375af32e75SAxel Dörfler 
6385af32e75SAxel Dörfler       assert (powers != &_fpioconst_pow10[0]);
6395af32e75SAxel Dörfler       do
6405af32e75SAxel Dörfler 	{
6415af32e75SAxel Dörfler 	  --powers;
6425af32e75SAxel Dörfler 
6435af32e75SAxel Dörfler 	  if (exponent >= powers->m_expo)
6445af32e75SAxel Dörfler 	    {
6455af32e75SAxel Dörfler 	      int i, incr, cnt_h, cnt_l;
6465af32e75SAxel Dörfler 	      mp_limb_t topval[2];
6475af32e75SAxel Dörfler 
6485af32e75SAxel Dörfler 	      /* The __mpn_mul function expects the first argument to be
6495af32e75SAxel Dörfler 		 bigger than the second.  */
6505af32e75SAxel Dörfler 	      if (fracsize < powers->arraysize - _FPIO_CONST_OFFSET)
6515af32e75SAxel Dörfler 		cy = __mpn_mul (tmp, &__tens[powers->arrayoff
6525af32e75SAxel Dörfler 					    + _FPIO_CONST_OFFSET],
6535af32e75SAxel Dörfler 				powers->arraysize - _FPIO_CONST_OFFSET,
6545af32e75SAxel Dörfler 				frac, fracsize);
6555af32e75SAxel Dörfler 	      else
6565af32e75SAxel Dörfler 		cy = __mpn_mul (tmp, frac, fracsize,
6575af32e75SAxel Dörfler 				&__tens[powers->arrayoff + _FPIO_CONST_OFFSET],
6585af32e75SAxel Dörfler 				powers->arraysize - _FPIO_CONST_OFFSET);
6595af32e75SAxel Dörfler 	      tmpsize = fracsize + powers->arraysize - _FPIO_CONST_OFFSET;
6605af32e75SAxel Dörfler 	      if (cy == 0)
6615af32e75SAxel Dörfler 		--tmpsize;
6625af32e75SAxel Dörfler 
6635af32e75SAxel Dörfler 	      count_leading_zeros (cnt_h, tmp[tmpsize - 1]);
6645af32e75SAxel Dörfler 	      incr = (tmpsize - fracsize) * BITS_PER_MP_LIMB
6655af32e75SAxel Dörfler 		     + BITS_PER_MP_LIMB - 1 - cnt_h;
6665af32e75SAxel Dörfler 
6675af32e75SAxel Dörfler 	      assert (incr <= powers->p_expo);
6685af32e75SAxel Dörfler 
6695af32e75SAxel Dörfler 	      /* If we increased the exponent by exactly 3 we have to test
6705af32e75SAxel Dörfler 		 for overflow.	This is done by comparing with 10 shifted
6715af32e75SAxel Dörfler 		 to the right position.	 */
6725af32e75SAxel Dörfler 	      if (incr == exponent + 3)
6735af32e75SAxel Dörfler 		{
6745af32e75SAxel Dörfler 		  if (cnt_h <= BITS_PER_MP_LIMB - 4)
6755af32e75SAxel Dörfler 		    {
6765af32e75SAxel Dörfler 		      topval[0] = 0;
6775af32e75SAxel Dörfler 		      topval[1]
6785af32e75SAxel Dörfler 			= ((mp_limb_t) 10) << (BITS_PER_MP_LIMB - 4 - cnt_h);
6795af32e75SAxel Dörfler 		    }
6805af32e75SAxel Dörfler 		  else
6815af32e75SAxel Dörfler 		    {
6825af32e75SAxel Dörfler 		      topval[0] = ((mp_limb_t) 10) << (BITS_PER_MP_LIMB - 4);
6835af32e75SAxel Dörfler 		      topval[1] = 0;
6845af32e75SAxel Dörfler 		      (void) __mpn_lshift (topval, topval, 2,
6855af32e75SAxel Dörfler 					   BITS_PER_MP_LIMB - cnt_h);
6865af32e75SAxel Dörfler 		    }
6875af32e75SAxel Dörfler 		}
6885af32e75SAxel Dörfler 
6895af32e75SAxel Dörfler 	      /* We have to be careful when multiplying the last factor.
6905af32e75SAxel Dörfler 		 If the result is greater than 1.0 be have to test it
6915af32e75SAxel Dörfler 		 against 10.0.  If it is greater or equal to 10.0 the
6925af32e75SAxel Dörfler 		 multiplication was not valid.  This is because we cannot
6935af32e75SAxel Dörfler 		 determine the number of bits in the result in advance.  */
6945af32e75SAxel Dörfler 	      if (incr < exponent + 3
6955af32e75SAxel Dörfler 		  || (incr == exponent + 3 &&
6965af32e75SAxel Dörfler 		      (tmp[tmpsize - 1] < topval[1]
6975af32e75SAxel Dörfler 		       || (tmp[tmpsize - 1] == topval[1]
6985af32e75SAxel Dörfler 			   && tmp[tmpsize - 2] < topval[0]))))
6995af32e75SAxel Dörfler 		{
7005af32e75SAxel Dörfler 		  /* The factor is right.  Adapt binary and decimal
7015af32e75SAxel Dörfler 		     exponents.	 */
7025af32e75SAxel Dörfler 		  exponent -= incr;
7035af32e75SAxel Dörfler 		  exp10 |= 1 << explog;
7045af32e75SAxel Dörfler 
7055af32e75SAxel Dörfler 		  /* If this factor yields a number greater or equal to
7065af32e75SAxel Dörfler 		     1.0, we must not shift the non-fractional digits down. */
7075af32e75SAxel Dörfler 		  if (exponent < 0)
7085af32e75SAxel Dörfler 		    cnt_h += -exponent;
7095af32e75SAxel Dörfler 
7105af32e75SAxel Dörfler 		  /* Now we optimize the number representation.	 */
7115af32e75SAxel Dörfler 		  for (i = 0; tmp[i] == 0; ++i);
7125af32e75SAxel Dörfler 		  if (cnt_h == BITS_PER_MP_LIMB - 1)
7135af32e75SAxel Dörfler 		    {
7145af32e75SAxel Dörfler 		      MPN_COPY (frac, tmp + i, tmpsize - i);
7155af32e75SAxel Dörfler 		      fracsize = tmpsize - i;
7165af32e75SAxel Dörfler 		    }
7175af32e75SAxel Dörfler 		  else
7185af32e75SAxel Dörfler 		    {
7195af32e75SAxel Dörfler 		      count_trailing_zeros (cnt_l, tmp[i]);
7205af32e75SAxel Dörfler 
7215af32e75SAxel Dörfler 		      /* Now shift the numbers to their optimal position.  */
7225af32e75SAxel Dörfler 		      if (i == 0 && BITS_PER_MP_LIMB - 1 - cnt_h > cnt_l)
7235af32e75SAxel Dörfler 			{
7245af32e75SAxel Dörfler 			  /* We cannot save any memory.	 Just roll the
7255af32e75SAxel Dörfler 			     number so that the leading digit is in a
7265af32e75SAxel Dörfler 			     separate limb.  */
7275af32e75SAxel Dörfler 
7285af32e75SAxel Dörfler 			  cy = __mpn_lshift (frac, tmp, tmpsize, cnt_h + 1);
7295af32e75SAxel Dörfler 			  fracsize = tmpsize + 1;
7305af32e75SAxel Dörfler 			  frac[fracsize - 1] = cy;
7315af32e75SAxel Dörfler 			}
7325af32e75SAxel Dörfler 		      else if (BITS_PER_MP_LIMB - 1 - cnt_h <= cnt_l)
7335af32e75SAxel Dörfler 			{
7345af32e75SAxel Dörfler 			  (void) __mpn_rshift (frac, tmp + i, tmpsize - i,
7355af32e75SAxel Dörfler 					       BITS_PER_MP_LIMB - 1 - cnt_h);
7365af32e75SAxel Dörfler 			  fracsize = tmpsize - i;
7375af32e75SAxel Dörfler 			}
7385af32e75SAxel Dörfler 		      else
7395af32e75SAxel Dörfler 			{
7405af32e75SAxel Dörfler 			  /* We can only save the memory of the limbs which
7415af32e75SAxel Dörfler 			     are zero.	The non-zero parts occupy the same
7425af32e75SAxel Dörfler 			     number of limbs.  */
7435af32e75SAxel Dörfler 
7445af32e75SAxel Dörfler 			  (void) __mpn_rshift (frac, tmp + (i - 1),
7455af32e75SAxel Dörfler 					       tmpsize - (i - 1),
7465af32e75SAxel Dörfler 					       BITS_PER_MP_LIMB - 1 - cnt_h);
7475af32e75SAxel Dörfler 			  fracsize = tmpsize - (i - 1);
7485af32e75SAxel Dörfler 			}
7495af32e75SAxel Dörfler 		    }
7505af32e75SAxel Dörfler 		  used_limbs = fracsize - 1;
7515af32e75SAxel Dörfler 		}
7525af32e75SAxel Dörfler 	    }
7535af32e75SAxel Dörfler 	  --explog;
7545af32e75SAxel Dörfler 	}
7555af32e75SAxel Dörfler       while (powers != &_fpioconst_pow10[1] && exponent > 0);
7565af32e75SAxel Dörfler       /* All factors but 10^-1 are tested now.	*/
7575af32e75SAxel Dörfler       if (exponent > 0)
7585af32e75SAxel Dörfler 	{
7595af32e75SAxel Dörfler 	  int cnt_l;
7605af32e75SAxel Dörfler 
7615af32e75SAxel Dörfler 	  cy = __mpn_mul_1 (tmp, frac, fracsize, 10);
7625af32e75SAxel Dörfler 	  tmpsize = fracsize;
7635af32e75SAxel Dörfler 	  assert (cy == 0 || tmp[tmpsize - 1] < 20);
7645af32e75SAxel Dörfler 
7655af32e75SAxel Dörfler 	  count_trailing_zeros (cnt_l, tmp[0]);
7665af32e75SAxel Dörfler 	  if (cnt_l < MIN (4, exponent))
7675af32e75SAxel Dörfler 	    {
7685af32e75SAxel Dörfler 	      cy = __mpn_lshift (frac, tmp, tmpsize,
7695af32e75SAxel Dörfler 				 BITS_PER_MP_LIMB - MIN (4, exponent));
7705af32e75SAxel Dörfler 	      if (cy != 0)
7715af32e75SAxel Dörfler 		frac[tmpsize++] = cy;
7725af32e75SAxel Dörfler 	    }
7735af32e75SAxel Dörfler 	  else
7745af32e75SAxel Dörfler 	    (void) __mpn_rshift (frac, tmp, tmpsize, MIN (4, exponent));
7755af32e75SAxel Dörfler 	  fracsize = tmpsize;
7765af32e75SAxel Dörfler 	  exp10 |= 1;
7775af32e75SAxel Dörfler 	  assert (frac[fracsize - 1] < 10);
7785af32e75SAxel Dörfler 	}
7795af32e75SAxel Dörfler       exponent = exp10;
7805af32e75SAxel Dörfler     }
7815af32e75SAxel Dörfler   else
7825af32e75SAxel Dörfler     {
7835af32e75SAxel Dörfler       /* This is a special case.  We don't need a factor because the
7845af32e75SAxel Dörfler 	 numbers are in the range of 0.0 <= fp < 8.0.  We simply
7855af32e75SAxel Dörfler 	 shift it to the right place and divide it by 1.0 to get the
7865af32e75SAxel Dörfler 	 leading digit.	 (Of course this division is not really made.)	*/
7875af32e75SAxel Dörfler       assert (0 <= exponent && exponent < 3 &&
7885af32e75SAxel Dörfler 	      exponent + to_shift < BITS_PER_MP_LIMB);
7895af32e75SAxel Dörfler 
7905af32e75SAxel Dörfler       /* Now shift the input value to its right place.	*/
7915af32e75SAxel Dörfler       cy = __mpn_lshift (frac, fp_input, fracsize, (exponent + to_shift));
7925af32e75SAxel Dörfler       frac[fracsize++] = cy;
7935af32e75SAxel Dörfler       exponent = 0;
7945af32e75SAxel Dörfler     }
7955af32e75SAxel Dörfler 
7965af32e75SAxel Dörfler   {
7975af32e75SAxel Dörfler     int width = info->width;
7985af32e75SAxel Dörfler     wchar_t *wbuffer, *wstartp, *wcp;
7995af32e75SAxel Dörfler     int buffer_malloced;
8005af32e75SAxel Dörfler     int chars_needed;
8015af32e75SAxel Dörfler     int expscale;
8025af32e75SAxel Dörfler     int intdig_max, intdig_no = 0;
8035af32e75SAxel Dörfler     int fracdig_min, fracdig_max, fracdig_no = 0;
8045af32e75SAxel Dörfler     int dig_max;
8055af32e75SAxel Dörfler     int significant;
8065af32e75SAxel Dörfler     int ngroups = 0;
8075af32e75SAxel Dörfler 
8085af32e75SAxel Dörfler     if (_tolower (info->spec) == 'e')
8095af32e75SAxel Dörfler       {
8105af32e75SAxel Dörfler 	type = info->spec;
8115af32e75SAxel Dörfler 	intdig_max = 1;
8125af32e75SAxel Dörfler 	fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
8135af32e75SAxel Dörfler 	chars_needed = 1 + 1 + fracdig_max + 1 + 1 + 4;
8145af32e75SAxel Dörfler 	/*	       d   .	 ddd	     e	 +-  ddd  */
8155af32e75SAxel Dörfler 	dig_max = INT_MAX;		/* Unlimited.  */
8165af32e75SAxel Dörfler 	significant = 1;		/* Does not matter here.  */
8175af32e75SAxel Dörfler       }
818*ae7395c8STrung Nguyen     else if (_tolower (info->spec) == 'f')
8195af32e75SAxel Dörfler       {
820*ae7395c8STrung Nguyen 	type = info->spec;
8215af32e75SAxel Dörfler 	fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
8225af32e75SAxel Dörfler 	if (expsign == 0)
8235af32e75SAxel Dörfler 	  {
8245af32e75SAxel Dörfler 	    intdig_max = exponent + 1;
8255af32e75SAxel Dörfler 	    /* This can be really big!	*/  /* XXX Maybe malloc if too big? */
8265af32e75SAxel Dörfler 	    chars_needed = exponent + 1 + 1 + fracdig_max;
8275af32e75SAxel Dörfler 	  }
8285af32e75SAxel Dörfler 	else
8295af32e75SAxel Dörfler 	  {
8305af32e75SAxel Dörfler 	    intdig_max = 1;
8315af32e75SAxel Dörfler 	    chars_needed = 1 + 1 + fracdig_max;
8325af32e75SAxel Dörfler 	  }
8335af32e75SAxel Dörfler 	dig_max = INT_MAX;		/* Unlimited.  */
8345af32e75SAxel Dörfler 	significant = 1;		/* Does not matter here.  */
8355af32e75SAxel Dörfler       }
8365af32e75SAxel Dörfler     else
8375af32e75SAxel Dörfler       {
8385af32e75SAxel Dörfler 	dig_max = info->prec < 0 ? 6 : (info->prec == 0 ? 1 : info->prec);
8395af32e75SAxel Dörfler 	if ((expsign == 0 && exponent >= dig_max)
8405af32e75SAxel Dörfler 	    || (expsign != 0 && exponent > 4))
8415af32e75SAxel Dörfler 	  {
8425af32e75SAxel Dörfler 	    if ('g' - 'G' == 'e' - 'E')
8435af32e75SAxel Dörfler 	      type = 'E' + (info->spec - 'G');
8445af32e75SAxel Dörfler 	    else
8455af32e75SAxel Dörfler 	      type = isupper (info->spec) ? 'E' : 'e';
8465af32e75SAxel Dörfler 	    fracdig_max = dig_max - 1;
8475af32e75SAxel Dörfler 	    intdig_max = 1;
8485af32e75SAxel Dörfler 	    chars_needed = 1 + 1 + fracdig_max + 1 + 1 + 4;
8495af32e75SAxel Dörfler 	  }
8505af32e75SAxel Dörfler 	else
8515af32e75SAxel Dörfler 	  {
8525af32e75SAxel Dörfler 	    type = 'f';
8535af32e75SAxel Dörfler 	    intdig_max = expsign == 0 ? exponent + 1 : 0;
8545af32e75SAxel Dörfler 	    fracdig_max = dig_max - intdig_max;
8555af32e75SAxel Dörfler 	    /* We need space for the significant digits and perhaps
8565af32e75SAxel Dörfler 	       for leading zeros when < 1.0.  The number of leading
8575af32e75SAxel Dörfler 	       zeros can be as many as would be required for
8585af32e75SAxel Dörfler 	       exponential notation with a negative two-digit
8595af32e75SAxel Dörfler 	       exponent, which is 4.  */
8605af32e75SAxel Dörfler 	    chars_needed = dig_max + 1 + 4;
8615af32e75SAxel Dörfler 	  }
8625af32e75SAxel Dörfler 	fracdig_min = info->alt ? fracdig_max : 0;
8635af32e75SAxel Dörfler 	significant = 0;		/* We count significant digits.	 */
8645af32e75SAxel Dörfler       }
8655af32e75SAxel Dörfler 
8665af32e75SAxel Dörfler     if (grouping)
8675af32e75SAxel Dörfler       {
8685af32e75SAxel Dörfler 	/* Guess the number of groups we will make, and thus how
8695af32e75SAxel Dörfler 	   many spaces we need for separator characters.  */
8705af32e75SAxel Dörfler 	ngroups = __guess_grouping (intdig_max, grouping);
8715af32e75SAxel Dörfler 	chars_needed += ngroups;
8725af32e75SAxel Dörfler       }
8735af32e75SAxel Dörfler 
8745af32e75SAxel Dörfler     /* Allocate buffer for output.  We need two more because while rounding
8755af32e75SAxel Dörfler        it is possible that we need two more characters in front of all the
8765af32e75SAxel Dörfler        other output.  If the amount of memory we have to allocate is too
8775af32e75SAxel Dörfler        large use `malloc' instead of `alloca'.  */
8785af32e75SAxel Dörfler     buffer_malloced = chars_needed > 5000;
8795af32e75SAxel Dörfler     if (buffer_malloced)
8805af32e75SAxel Dörfler       {
8815af32e75SAxel Dörfler 	wbuffer = (wchar_t *) malloc ((2 + chars_needed) * sizeof (wchar_t));
8825af32e75SAxel Dörfler 	if (wbuffer == NULL)
8835af32e75SAxel Dörfler 	  /* Signal an error to the caller.  */
8845af32e75SAxel Dörfler 	  return -1;
8855af32e75SAxel Dörfler       }
8865af32e75SAxel Dörfler     else
8875af32e75SAxel Dörfler       wbuffer = (wchar_t *) alloca ((2 + chars_needed) * sizeof (wchar_t));
8885af32e75SAxel Dörfler     wcp = wstartp = wbuffer + 2;	/* Let room for rounding.  */
8895af32e75SAxel Dörfler 
8905af32e75SAxel Dörfler     /* Do the real work: put digits in allocated buffer.  */
891*ae7395c8STrung Nguyen     if (expsign == 0 || _tolower (type) != 'f')
8925af32e75SAxel Dörfler       {
8935af32e75SAxel Dörfler 	assert (expsign == 0 || intdig_max == 1);
8945af32e75SAxel Dörfler 	while (intdig_no < intdig_max)
8955af32e75SAxel Dörfler 	  {
8965af32e75SAxel Dörfler 	    ++intdig_no;
89738fee4c3SJonathan Schleifer 	    hack_digit_callee = 1;
89838fee4c3SJonathan Schleifer 	    goto hack_digit;
89938fee4c3SJonathan Schleifer hack_digit_callee1:
90038fee4c3SJonathan Schleifer 	    *wcp++ = hack_digit_ret;
9015af32e75SAxel Dörfler 	  }
9025af32e75SAxel Dörfler 	significant = 1;
9035af32e75SAxel Dörfler 	if (info->alt
9045af32e75SAxel Dörfler 	    || fracdig_min > 0
9055af32e75SAxel Dörfler 	    || (fracdig_max > 0 && (fracsize > 1 || frac[0] != 0)))
9065af32e75SAxel Dörfler 	  *wcp++ = decimalwc;
9075af32e75SAxel Dörfler       }
9085af32e75SAxel Dörfler     else
9095af32e75SAxel Dörfler       {
9105af32e75SAxel Dörfler 	/* |fp| < 1.0 and the selected type is 'f', so put "0."
9115af32e75SAxel Dörfler 	   in the buffer.  */
9125af32e75SAxel Dörfler 	*wcp++ = L'0';
9135af32e75SAxel Dörfler 	--exponent;
9145af32e75SAxel Dörfler 	*wcp++ = decimalwc;
9155af32e75SAxel Dörfler       }
9165af32e75SAxel Dörfler 
9175af32e75SAxel Dörfler     /* Generate the needed number of fractional digits.	 */
9185af32e75SAxel Dörfler     while (fracdig_no < fracdig_min
9195af32e75SAxel Dörfler 	   || (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
9205af32e75SAxel Dörfler       {
9215af32e75SAxel Dörfler 	++fracdig_no;
92238fee4c3SJonathan Schleifer 	hack_digit_callee = 2;
92338fee4c3SJonathan Schleifer 	goto hack_digit;
92438fee4c3SJonathan Schleifer hack_digit_callee2:
925d1c7f766SJonathan Schleifer 	*wcp = hack_digit_ret;
9265af32e75SAxel Dörfler 	if (*wcp != L'0')
9275af32e75SAxel Dörfler 	  significant = 1;
9285af32e75SAxel Dörfler 	else if (significant == 0)
9295af32e75SAxel Dörfler 	  {
9305af32e75SAxel Dörfler 	    ++fracdig_max;
9315af32e75SAxel Dörfler 	    if (fracdig_min > 0)
9325af32e75SAxel Dörfler 	      ++fracdig_min;
9335af32e75SAxel Dörfler 	  }
9345af32e75SAxel Dörfler 	++wcp;
9355af32e75SAxel Dörfler       }
9365af32e75SAxel Dörfler 
9375af32e75SAxel Dörfler     /* Do rounding.  */
93838fee4c3SJonathan Schleifer     hack_digit_callee = 3;
93938fee4c3SJonathan Schleifer     goto hack_digit;
94038fee4c3SJonathan Schleifer hack_digit_callee3:
94138fee4c3SJonathan Schleifer     digit = hack_digit_ret;
9425af32e75SAxel Dörfler     if (digit > L'4')
9435af32e75SAxel Dörfler       {
9445af32e75SAxel Dörfler 	wchar_t *wtp = wcp;
9455af32e75SAxel Dörfler 
9465af32e75SAxel Dörfler 	if (digit == L'5'
9475af32e75SAxel Dörfler 	    && ((*(wcp - 1) != decimalwc && (*(wcp - 1) & 1) == 0)
9485af32e75SAxel Dörfler 		|| ((*(wcp - 1) == decimalwc && (*(wcp - 2) & 1) == 0))))
9495af32e75SAxel Dörfler 	  {
9505af32e75SAxel Dörfler 	    /* This is the critical case.	 */
9515af32e75SAxel Dörfler 	    if (fracsize == 1 && frac[0] == 0)
9525af32e75SAxel Dörfler 	      /* Rest of the number is zero -> round to even.
9535af32e75SAxel Dörfler 		 (IEEE 754-1985 4.1 says this is the default rounding.)  */
9545af32e75SAxel Dörfler 	      goto do_expo;
9555af32e75SAxel Dörfler 	    else if (scalesize == 0)
9565af32e75SAxel Dörfler 	      {
9575af32e75SAxel Dörfler 		/* Here we have to see whether all limbs are zero since no
9585af32e75SAxel Dörfler 		   normalization happened.  */
9595af32e75SAxel Dörfler 		size_t lcnt = fracsize;
9605af32e75SAxel Dörfler 		while (lcnt >= 1 && frac[lcnt - 1] == 0)
9615af32e75SAxel Dörfler 		  --lcnt;
9625af32e75SAxel Dörfler 		if (lcnt == 0)
9635af32e75SAxel Dörfler 		  /* Rest of the number is zero -> round to even.
9645af32e75SAxel Dörfler 		     (IEEE 754-1985 4.1 says this is the default rounding.)  */
9655af32e75SAxel Dörfler 		  goto do_expo;
9665af32e75SAxel Dörfler 	      }
9675af32e75SAxel Dörfler 	  }
9685af32e75SAxel Dörfler 
9695af32e75SAxel Dörfler 	if (fracdig_no > 0)
9705af32e75SAxel Dörfler 	  {
9715af32e75SAxel Dörfler 	    /* Process fractional digits.  Terminate if not rounded or
9725af32e75SAxel Dörfler 	       radix character is reached.  */
9735af32e75SAxel Dörfler 	    while (*--wtp != decimalwc && *wtp == L'9')
9745af32e75SAxel Dörfler 	      *wtp = '0';
9755af32e75SAxel Dörfler 	    if (*wtp != decimalwc)
9765af32e75SAxel Dörfler 	      /* Round up.  */
9775af32e75SAxel Dörfler 	      (*wtp)++;
9785af32e75SAxel Dörfler 	  }
9795af32e75SAxel Dörfler 
9805af32e75SAxel Dörfler 	if (fracdig_no == 0 || *wtp == decimalwc)
9815af32e75SAxel Dörfler 	  {
9825af32e75SAxel Dörfler 	    /* Round the integer digits.  */
9835af32e75SAxel Dörfler 	    if (*(wtp - 1) == decimalwc)
9845af32e75SAxel Dörfler 	      --wtp;
9855af32e75SAxel Dörfler 
9865af32e75SAxel Dörfler 	    while (--wtp >= wstartp && *wtp == L'9')
9875af32e75SAxel Dörfler 	      *wtp = L'0';
9885af32e75SAxel Dörfler 
9895af32e75SAxel Dörfler 	    if (wtp >= wstartp)
9905af32e75SAxel Dörfler 	      /* Round up.  */
9915af32e75SAxel Dörfler 	      (*wtp)++;
9925af32e75SAxel Dörfler 	    else
9935af32e75SAxel Dörfler 	      /* It is more critical.  All digits were 9's.  */
9945af32e75SAxel Dörfler 	      {
995*ae7395c8STrung Nguyen 		if (_tolower (type) != 'f')
9965af32e75SAxel Dörfler 		  {
9975af32e75SAxel Dörfler 		    *wstartp = '1';
9985af32e75SAxel Dörfler 		    exponent += expsign == 0 ? 1 : -1;
9995af32e75SAxel Dörfler 		  }
10005af32e75SAxel Dörfler 		else if (intdig_no == dig_max)
10015af32e75SAxel Dörfler 		  {
10025af32e75SAxel Dörfler 		    /* This is the case where for type %g the number fits
10035af32e75SAxel Dörfler 		       really in the range for %f output but after rounding
10045af32e75SAxel Dörfler 		       the number of digits is too big.	 */
10055af32e75SAxel Dörfler 		    *--wstartp = decimalwc;
10065af32e75SAxel Dörfler 		    *--wstartp = L'1';
10075af32e75SAxel Dörfler 
10085af32e75SAxel Dörfler 		    if (info->alt || fracdig_no > 0)
10095af32e75SAxel Dörfler 		      {
10105af32e75SAxel Dörfler 			/* Overwrite the old radix character.  */
10115af32e75SAxel Dörfler 			wstartp[intdig_no + 2] = L'0';
10125af32e75SAxel Dörfler 			++fracdig_no;
10135af32e75SAxel Dörfler 		      }
10145af32e75SAxel Dörfler 
10155af32e75SAxel Dörfler 		    fracdig_no += intdig_no;
10165af32e75SAxel Dörfler 		    intdig_no = 1;
10175af32e75SAxel Dörfler 		    fracdig_max = intdig_max - intdig_no;
10185af32e75SAxel Dörfler 		    ++exponent;
10195af32e75SAxel Dörfler 		    /* Now we must print the exponent.	*/
10205af32e75SAxel Dörfler 		    type = isupper (info->spec) ? 'E' : 'e';
10215af32e75SAxel Dörfler 		  }
10225af32e75SAxel Dörfler 		else
10235af32e75SAxel Dörfler 		  {
10245af32e75SAxel Dörfler 		    /* We can simply add another another digit before the
10255af32e75SAxel Dörfler 		       radix.  */
10265af32e75SAxel Dörfler 		    *--wstartp = L'1';
10275af32e75SAxel Dörfler 		    ++intdig_no;
10285af32e75SAxel Dörfler 		  }
10295af32e75SAxel Dörfler 
10305af32e75SAxel Dörfler 		/* While rounding the number of digits can change.
10315af32e75SAxel Dörfler 		   If the number now exceeds the limits remove some
10325af32e75SAxel Dörfler 		   fractional digits.  */
10335af32e75SAxel Dörfler 		if (intdig_no + fracdig_no > dig_max)
10345af32e75SAxel Dörfler 		  {
10355af32e75SAxel Dörfler 		    wcp -= intdig_no + fracdig_no - dig_max;
10365af32e75SAxel Dörfler 		    fracdig_no -= intdig_no + fracdig_no - dig_max;
10375af32e75SAxel Dörfler 		  }
10385af32e75SAxel Dörfler 	      }
10395af32e75SAxel Dörfler 	  }
10405af32e75SAxel Dörfler       }
10415af32e75SAxel Dörfler 
10425af32e75SAxel Dörfler   do_expo:
10435af32e75SAxel Dörfler     /* Now remove unnecessary '0' at the end of the string.  */
10445af32e75SAxel Dörfler     while (fracdig_no > fracdig_min && *(wcp - 1) == L'0')
10455af32e75SAxel Dörfler       {
10465af32e75SAxel Dörfler 	--wcp;
10475af32e75SAxel Dörfler 	--fracdig_no;
10485af32e75SAxel Dörfler       }
10495af32e75SAxel Dörfler     /* If we eliminate all fractional digits we perhaps also can remove
10505af32e75SAxel Dörfler        the radix character.  */
10515af32e75SAxel Dörfler     if (fracdig_no == 0 && !info->alt && *(wcp - 1) == decimalwc)
10525af32e75SAxel Dörfler       --wcp;
10535af32e75SAxel Dörfler 
10545af32e75SAxel Dörfler     if (grouping)
10555af32e75SAxel Dörfler       /* Add in separator characters, overwriting the same buffer.  */
10565af32e75SAxel Dörfler       wcp = group_number (wstartp, wcp, intdig_no, grouping, thousands_sepwc,
10575af32e75SAxel Dörfler 			  ngroups);
10585af32e75SAxel Dörfler 
10595af32e75SAxel Dörfler     /* Write the exponent if it is needed.  */
1060*ae7395c8STrung Nguyen     if (_tolower (type) != 'f')
10615af32e75SAxel Dörfler       {
10625af32e75SAxel Dörfler 	*wcp++ = (wchar_t) type;
10635af32e75SAxel Dörfler 	*wcp++ = expsign ? L'-' : L'+';
10645af32e75SAxel Dörfler 
10655af32e75SAxel Dörfler 	/* Find the magnitude of the exponent.	*/
10665af32e75SAxel Dörfler 	expscale = 10;
10675af32e75SAxel Dörfler 	while (expscale <= exponent)
10685af32e75SAxel Dörfler 	  expscale *= 10;
10695af32e75SAxel Dörfler 
10705af32e75SAxel Dörfler 	if (exponent < 10)
10715af32e75SAxel Dörfler 	  /* Exponent always has at least two digits.  */
10725af32e75SAxel Dörfler 	  *wcp++ = L'0';
10735af32e75SAxel Dörfler 	else
10745af32e75SAxel Dörfler 	  do
10755af32e75SAxel Dörfler 	    {
10765af32e75SAxel Dörfler 	      expscale /= 10;
10775af32e75SAxel Dörfler 	      *wcp++ = L'0' + (exponent / expscale);
10785af32e75SAxel Dörfler 	      exponent %= expscale;
10795af32e75SAxel Dörfler 	    }
10805af32e75SAxel Dörfler 	  while (expscale > 10);
10815af32e75SAxel Dörfler 	*wcp++ = L'0' + exponent;
10825af32e75SAxel Dörfler       }
10835af32e75SAxel Dörfler 
10845af32e75SAxel Dörfler     /* Compute number of characters which must be filled with the padding
10855af32e75SAxel Dörfler        character.  */
10865af32e75SAxel Dörfler     if (is_neg || info->showsign || info->space)
10875af32e75SAxel Dörfler       --width;
10885af32e75SAxel Dörfler     width -= wcp - wstartp;
10895af32e75SAxel Dörfler 
10905af32e75SAxel Dörfler     if (!info->left && info->pad != '0' && width > 0)
10915af32e75SAxel Dörfler       PADN (info->pad, width);
10925af32e75SAxel Dörfler 
10935af32e75SAxel Dörfler     if (is_neg)
10945af32e75SAxel Dörfler       outchar ('-');
10955af32e75SAxel Dörfler     else if (info->showsign)
10965af32e75SAxel Dörfler       outchar ('+');
10975af32e75SAxel Dörfler     else if (info->space)
10985af32e75SAxel Dörfler       outchar (' ');
10995af32e75SAxel Dörfler 
11005af32e75SAxel Dörfler     if (!info->left && info->pad == '0' && width > 0)
11015af32e75SAxel Dörfler       PADN ('0', width);
11025af32e75SAxel Dörfler 
11035af32e75SAxel Dörfler     {
11045af32e75SAxel Dörfler       char *buffer = NULL;
11055af32e75SAxel Dörfler       char *cp = NULL;
11065af32e75SAxel Dörfler       char *tmpptr;
11075af32e75SAxel Dörfler 
11085af32e75SAxel Dörfler       if (! wide)
11095af32e75SAxel Dörfler 	{
11105af32e75SAxel Dörfler 	  /* Create the single byte string.  */
11115af32e75SAxel Dörfler 	  size_t decimal_len;
11125af32e75SAxel Dörfler 	  size_t thousands_sep_len;
11135af32e75SAxel Dörfler 	  wchar_t *copywc;
11145af32e75SAxel Dörfler 
11155af32e75SAxel Dörfler 	  decimal_len = strlen (decimal);
11165af32e75SAxel Dörfler 
11175af32e75SAxel Dörfler 	  if (thousands_sep == NULL)
11185af32e75SAxel Dörfler 	    thousands_sep_len = 0;
11195af32e75SAxel Dörfler 	  else
11205af32e75SAxel Dörfler 	    thousands_sep_len = strlen (thousands_sep);
11215af32e75SAxel Dörfler 
11225af32e75SAxel Dörfler 	  if (buffer_malloced)
11235af32e75SAxel Dörfler 	    {
11245af32e75SAxel Dörfler 	      buffer = (char *) malloc (2 + chars_needed + decimal_len
11255af32e75SAxel Dörfler 					+ ngroups * thousands_sep_len);
11265af32e75SAxel Dörfler 	      if (buffer == NULL)
11275af32e75SAxel Dörfler 		/* Signal an error to the caller.  */
11285af32e75SAxel Dörfler 		return -1;
11295af32e75SAxel Dörfler 	    }
11305af32e75SAxel Dörfler 	  else
11315af32e75SAxel Dörfler 	    buffer = (char *) alloca (2 + chars_needed + decimal_len
11325af32e75SAxel Dörfler 				      + ngroups * thousands_sep_len);
11335af32e75SAxel Dörfler 
11345af32e75SAxel Dörfler 	  /* Now copy the wide character string.  Since the character
11355af32e75SAxel Dörfler 	     (except for the decimal point and thousands separator) must
11365af32e75SAxel Dörfler 	     be coming from the ASCII range we can esily convert the
11375af32e75SAxel Dörfler 	     string without mapping tables.  */
11385af32e75SAxel Dörfler 	  for (cp = buffer, copywc = wstartp; copywc < wcp; ++copywc)
11395af32e75SAxel Dörfler 	    if (*copywc == decimalwc)
11405af32e75SAxel Dörfler 	      cp = (char *) __mempcpy (cp, decimal, decimal_len);
11415af32e75SAxel Dörfler 	    else if (*copywc == thousands_sepwc)
11425af32e75SAxel Dörfler 	      cp = (char *) __mempcpy (cp, thousands_sep, thousands_sep_len);
11435af32e75SAxel Dörfler 	    else
11445af32e75SAxel Dörfler 	      *cp++ = (char) *copywc;
11455af32e75SAxel Dörfler 	}
11465af32e75SAxel Dörfler 
11475af32e75SAxel Dörfler       tmpptr = buffer;
11485af32e75SAxel Dörfler       PRINT (tmpptr, wstartp, wide ? wcp - wstartp : cp - tmpptr);
11495af32e75SAxel Dörfler 
11505af32e75SAxel Dörfler       /* Free the memory if necessary.  */
11515af32e75SAxel Dörfler       if (buffer_malloced)
11525af32e75SAxel Dörfler 	{
11535af32e75SAxel Dörfler 	  free (buffer);
11545af32e75SAxel Dörfler 	  free (wbuffer);
11555af32e75SAxel Dörfler 	}
11565af32e75SAxel Dörfler     }
11575af32e75SAxel Dörfler 
11585af32e75SAxel Dörfler     if (info->left && width > 0)
11595af32e75SAxel Dörfler       PADN (info->pad, width);
11605af32e75SAxel Dörfler   }
11615af32e75SAxel Dörfler   return done;
11625af32e75SAxel Dörfler }
11639e419c30SAugustin Cavalier 
11645af32e75SAxel Dörfler /* Return the number of extra grouping characters that will be inserted
11655af32e75SAxel Dörfler    into a number with INTDIG_MAX integer digits.  */
11665af32e75SAxel Dörfler 
11675af32e75SAxel Dörfler unsigned int
__guess_grouping(unsigned int intdig_max,const char * grouping)11685af32e75SAxel Dörfler __guess_grouping (unsigned int intdig_max, const char *grouping)
11695af32e75SAxel Dörfler {
11705af32e75SAxel Dörfler   unsigned int groups;
11715af32e75SAxel Dörfler 
11725af32e75SAxel Dörfler   /* We treat all negative values like CHAR_MAX.  */
11735af32e75SAxel Dörfler 
11745af32e75SAxel Dörfler   if (*grouping == CHAR_MAX || *grouping <= 0)
11755af32e75SAxel Dörfler     /* No grouping should be done.  */
11765af32e75SAxel Dörfler     return 0;
11775af32e75SAxel Dörfler 
11785af32e75SAxel Dörfler   groups = 0;
11795af32e75SAxel Dörfler   while (intdig_max > (unsigned int) *grouping)
11805af32e75SAxel Dörfler     {
11815af32e75SAxel Dörfler       ++groups;
11825af32e75SAxel Dörfler       intdig_max -= *grouping++;
11835af32e75SAxel Dörfler 
11845af32e75SAxel Dörfler       if (*grouping == CHAR_MAX
11855af32e75SAxel Dörfler #if CHAR_MIN < 0
11865af32e75SAxel Dörfler 	  || *grouping < 0
11875af32e75SAxel Dörfler #endif
11885af32e75SAxel Dörfler 	  )
11895af32e75SAxel Dörfler 	/* No more grouping should be done.  */
11905af32e75SAxel Dörfler 	break;
11915af32e75SAxel Dörfler       else if (*grouping == 0)
11925af32e75SAxel Dörfler 	{
11935af32e75SAxel Dörfler 	  /* Same grouping repeats.  */
11945af32e75SAxel Dörfler 	  groups += (intdig_max - 1) / grouping[-1];
11955af32e75SAxel Dörfler 	  break;
11965af32e75SAxel Dörfler 	}
11975af32e75SAxel Dörfler     }
11985af32e75SAxel Dörfler 
11995af32e75SAxel Dörfler   return groups;
12005af32e75SAxel Dörfler }
12015af32e75SAxel Dörfler 
12025af32e75SAxel Dörfler /* Group the INTDIG_NO integer digits of the number in [BUF,BUFEND).
12035af32e75SAxel Dörfler    There is guaranteed enough space past BUFEND to extend it.
12045af32e75SAxel Dörfler    Return the new end of buffer.  */
12055af32e75SAxel Dörfler 
12065af32e75SAxel Dörfler static wchar_t *
12075af32e75SAxel Dörfler internal_function
group_number(wchar_t * buf,wchar_t * bufend,unsigned int intdig_no,const char * grouping,wchar_t thousands_sep,int ngroups)12085af32e75SAxel Dörfler group_number (wchar_t *buf, wchar_t *bufend, unsigned int intdig_no,
12095af32e75SAxel Dörfler 	      const char *grouping, wchar_t thousands_sep, int ngroups)
12105af32e75SAxel Dörfler {
12115af32e75SAxel Dörfler   wchar_t *p;
12125af32e75SAxel Dörfler 
12135af32e75SAxel Dörfler   if (ngroups == 0)
12145af32e75SAxel Dörfler     return bufend;
12155af32e75SAxel Dörfler 
12165af32e75SAxel Dörfler   /* Move the fractional part down.  */
12175af32e75SAxel Dörfler   __wmemmove (buf + intdig_no + ngroups, buf + intdig_no,
12185af32e75SAxel Dörfler 	      bufend - (buf + intdig_no));
12195af32e75SAxel Dörfler 
12205af32e75SAxel Dörfler   p = buf + intdig_no + ngroups - 1;
12215af32e75SAxel Dörfler   do
12225af32e75SAxel Dörfler     {
12235af32e75SAxel Dörfler       unsigned int len = *grouping++;
12245af32e75SAxel Dörfler       do
12255af32e75SAxel Dörfler 	*p-- = buf[--intdig_no];
12265af32e75SAxel Dörfler       while (--len > 0);
12275af32e75SAxel Dörfler       *p-- = thousands_sep;
12285af32e75SAxel Dörfler 
12295af32e75SAxel Dörfler       if (*grouping == CHAR_MAX
12305af32e75SAxel Dörfler #if CHAR_MIN < 0
12315af32e75SAxel Dörfler 	  || *grouping < 0
12325af32e75SAxel Dörfler #endif
12335af32e75SAxel Dörfler 	  )
12345af32e75SAxel Dörfler 	/* No more grouping should be done.  */
12355af32e75SAxel Dörfler 	break;
12365af32e75SAxel Dörfler       else if (*grouping == 0)
12375af32e75SAxel Dörfler 	/* Same grouping repeats.  */
12385af32e75SAxel Dörfler 	--grouping;
12395af32e75SAxel Dörfler     } while (intdig_no > (unsigned int) *grouping);
12405af32e75SAxel Dörfler 
12415af32e75SAxel Dörfler   /* Copy the remaining ungrouped digits.  */
12425af32e75SAxel Dörfler   do
12435af32e75SAxel Dörfler     *p-- = buf[--intdig_no];
12445af32e75SAxel Dörfler   while (p > buf);
12455af32e75SAxel Dörfler 
12465af32e75SAxel Dörfler   return bufend + ngroups;
12475af32e75SAxel Dörfler }
1248