Home | History | Annotate | Line # | Download | only in printf
      1 /* Floating point output for `printf'.
      2    Copyright (C) 1995-2012 Free Software Foundation, Inc.
      3 
      4    This file is part of the GNU C Library.
      5    Written by Ulrich Drepper <drepper (at) gnu.ai.mit.edu>, 1995.
      6 
      7    The GNU C Library is free software; you can redistribute it and/or
      8    modify it under the terms of the GNU Lesser General Public
      9    License as published by the Free Software Foundation; either
     10    version 2.1 of the License, or (at your option) any later version.
     11 
     12    The GNU C Library is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15    Lesser General Public License for more details.
     16 
     17    You should have received a copy of the GNU Lesser General Public
     18    License along with the GNU C Library; if not, see
     19    <http://www.gnu.org/licenses/>.  */
     20 
     21 #include <config.h>
     22 #include <float.h>
     23 #include <limits.h>
     24 #include <math.h>
     25 #include <string.h>
     26 #include <unistd.h>
     27 #include <stdlib.h>
     28 #include <stdbool.h>
     29 #define NDEBUG
     30 #include <assert.h>
     31 #ifdef HAVE_ERRNO_H
     32 #include <errno.h>
     33 #endif
     34 #include <stdio.h>
     35 #include <stdarg.h>
     36 #ifdef HAVE_FENV_H
     37 #include "quadmath-rounding-mode.h"
     38 #endif
     39 #include "quadmath-printf.h"
     40 #include "fpioconst.h"
     41 
     42 #ifdef USE_I18N_NUMBER_H
     43 #include "_i18n_number.h"
     44 #endif
     45 
     46 
     47 /* Macros for doing the actual output.  */
     49 
     50 #define outchar(ch)							      \
     51   do									      \
     52     {									      \
     53       register const int outc = (ch);					      \
     54       if (PUTC (outc, fp) == EOF)					      \
     55 	{								      \
     56 	  if (buffer_malloced)						      \
     57 	    free (wbuffer);						      \
     58 	  return -1;							      \
     59 	}								      \
     60       ++done;								      \
     61     } while (0)
     62 
     63 #define PRINT(ptr, wptr, len)						      \
     64   do									      \
     65     {									      \
     66       register size_t outlen = (len);					      \
     67       if (len > 20)							      \
     68 	{								      \
     69 	  if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
     70 	    {								      \
     71 	      if (buffer_malloced)					      \
     72 		free (wbuffer);						      \
     73 	      return -1;						      \
     74 	    }								      \
     75 	  ptr += outlen;						      \
     76 	  done += outlen;						      \
     77 	}								      \
     78       else								      \
     79 	{								      \
     80 	  if (wide)							      \
     81 	    while (outlen-- > 0)					      \
     82 	      outchar (*wptr++);					      \
     83 	  else								      \
     84 	    while (outlen-- > 0)					      \
     85 	      outchar (*ptr++);						      \
     86 	}								      \
     87     } while (0)
     88 
     89 #define PADN(ch, len)							      \
     90   do									      \
     91     {									      \
     92       if (PAD (fp, ch, len) != len)					      \
     93 	{								      \
     94 	  if (buffer_malloced)						      \
     95 	    free (wbuffer);						      \
     96 	  return -1;							      \
     97 	}								      \
     98       done += len;							      \
     99     }									      \
    100   while (0)
    101 
    102 
    103 /* We use the GNU MP library to handle large numbers.
    105 
    106    An MP variable occupies a varying number of entries in its array.  We keep
    107    track of this number for efficiency reasons.  Otherwise we would always
    108    have to process the whole array.  */
    109 #define MPN_VAR(name) mp_limb_t *name; mp_size_t name##size
    110 
    111 #define MPN_ASSIGN(dst,src)						      \
    112   memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb_t))
    113 #define MPN_GE(u,v) \
    114   (u##size > v##size || (u##size == v##size && mpn_cmp (u, v, u##size) >= 0))
    115 
    116 extern mp_size_t mpn_extract_flt128 (mp_ptr res_ptr, mp_size_t size,
    117 				     int *expt, int *is_neg,
    118 				     __float128 value) attribute_hidden;
    119 static unsigned int guess_grouping (unsigned int intdig_max,
    120 				    const char *grouping);
    121 
    122 
    123 static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
    124 			      unsigned int intdig_no, const char *grouping,
    125 			      wchar_t thousands_sep, int ngroups);
    126 
    127 
    128 int
    129 __quadmath_printf_fp (struct __quadmath_printf_file *fp,
    130 		      const struct printf_info *info,
    131 		      const void *const *args)
    132 {
    133   /* The floating-point value to output.  */
    134   __float128 fpnum;
    135 
    136   /* Locale-dependent representation of decimal point.	*/
    137   const char *decimal;
    138   wchar_t decimalwc;
    139 
    140   /* Locale-dependent thousands separator and grouping specification.  */
    141   const char *thousands_sep = NULL;
    142   wchar_t thousands_sepwc = L_('\0');
    143   const char *grouping;
    144 
    145   /* "NaN" or "Inf" for the special cases.  */
    146   const char *special = NULL;
    147   const wchar_t *wspecial = NULL;
    148 
    149   /* We need just a few limbs for the input before shifting to the right
    150      position.	*/
    151   mp_limb_t fp_input[(FLT128_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB];
    152   /* We need to shift the contents of fp_input by this amount of bits.	*/
    153   int to_shift = 0;
    154 
    155   /* The fraction of the floting-point value in question  */
    156   MPN_VAR(frac);
    157   /* and the exponent.	*/
    158   int exponent;
    159   /* Sign of the exponent.  */
    160   int expsign = 0;
    161   /* Sign of float number.  */
    162   int is_neg = 0;
    163 
    164   /* Scaling factor.  */
    165   MPN_VAR(scale);
    166 
    167   /* Temporary bignum value.  */
    168   MPN_VAR(tmp);
    169 
    170   /* Digit which is result of last hack_digit() call.  */
    171   wchar_t last_digit, next_digit;
    172   bool more_bits;
    173 
    174   /* The type of output format that will be used: 'e'/'E' or 'f'.  */
    175   int type;
    176 
    177   /* Counter for number of written characters.	*/
    178   int done = 0;
    179 
    180   /* General helper (carry limb).  */
    181   mp_limb_t cy;
    182 
    183   /* Nonzero if this is output on a wide character stream.  */
    184   int wide = info->wide;
    185 
    186   /* Buffer in which we produce the output.  */
    187   wchar_t *wbuffer = NULL;
    188   /* Flag whether wbuffer is malloc'ed or not.  */
    189   int buffer_malloced = 0;
    190 
    191   auto wchar_t hack_digit (void);
    192 
    193   wchar_t hack_digit (void)
    194     {
    195       mp_limb_t hi;
    196 
    197       if (expsign != 0 && type == 'f' && exponent-- > 0)
    198 	hi = 0;
    199       else if (scalesize == 0)
    200 	{
    201 	  hi = frac[fracsize - 1];
    202 	  frac[fracsize - 1] = mpn_mul_1 (frac, frac, fracsize - 1, 10);
    203 	}
    204       else
    205 	{
    206 	  if (fracsize < scalesize)
    207 	    hi = 0;
    208 	  else
    209 	    {
    210 	      hi = mpn_divmod (tmp, frac, fracsize, scale, scalesize);
    211 	      tmp[fracsize - scalesize] = hi;
    212 	      hi = tmp[0];
    213 
    214 	      fracsize = scalesize;
    215 	      while (fracsize != 0 && frac[fracsize - 1] == 0)
    216 		--fracsize;
    217 	      if (fracsize == 0)
    218 		{
    219 		  /* We're not prepared for an mpn variable with zero
    220 		     limbs.  */
    221 		  fracsize = 1;
    222 		  return L_('0') + hi;
    223 		}
    224 	    }
    225 
    226 	  mp_limb_t _cy = mpn_mul_1 (frac, frac, fracsize, 10);
    227 	  if (_cy != 0)
    228 	    frac[fracsize++] = _cy;
    229 	}
    230 
    231       return L_('0') + hi;
    232     }
    233 
    234   /* Figure out the decimal point character.  */
    235 #ifdef USE_NL_LANGINFO
    236   if (info->extra == 0)
    237     decimal = nl_langinfo (DECIMAL_POINT);
    238   else
    239     {
    240       decimal = nl_langinfo (MON_DECIMAL_POINT);
    241       if (*decimal == '\0')
    242 	decimal = nl_langinfo (DECIMAL_POINT);
    243     }
    244   /* The decimal point character must never be zero.  */
    245   assert (*decimal != '\0');
    246 #elif defined USE_LOCALECONV
    247   const struct lconv *lc = localeconv ();
    248   if (info->extra == 0)
    249     decimal = lc->decimal_point;
    250   else
    251     {
    252       decimal = lc->mon_decimal_point;
    253       if (decimal == NULL || *decimal == '\0')
    254 	decimal = lc->decimal_point;
    255     }
    256   if (decimal == NULL || *decimal == '\0')
    257     decimal = ".";
    258 #else
    259   decimal = ".";
    260 #endif
    261 #ifdef USE_NL_LANGINFO_WC
    262   if (info->extra == 0)
    263     decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
    264   else
    265     {
    266       decimalwc = nl_langinfo_wc (_NL_MONETARY_DECIMAL_POINT_WC);
    267       if (decimalwc == L_('\0'))
    268 	decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
    269     }
    270   /* The decimal point character must never be zero.  */
    271   assert (decimalwc != L_('\0'));
    272 #else
    273   decimalwc = L_('.');
    274 #endif
    275 
    276 #if defined USE_NL_LANGINFO && defined USE_NL_LANGINFO_WC
    277   if (info->group)
    278     {
    279       if (info->extra == 0)
    280 	grouping = nl_langinfo (GROUPING);
    281       else
    282 	grouping = nl_langinfo (MON_GROUPING);
    283 
    284       if (*grouping <= 0 || *grouping == CHAR_MAX)
    285 	grouping = NULL;
    286       else
    287 	{
    288 	  /* Figure out the thousands separator character.  */
    289 	  if (wide)
    290 	    {
    291 	      if (info->extra == 0)
    292 		thousands_sepwc = nl_langinfo_wc (_NL_NUMERIC_THOUSANDS_SEP_WC);
    293 	      else
    294 		thousands_sepwc = nl_langinfo_wc (_NL_MONETARY_THOUSANDS_SEP_WC);
    295 
    296 	      if (thousands_sepwc == L_('\0'))
    297 		grouping = NULL;
    298 	    }
    299 	  else
    300 	    {
    301 	      if (info->extra == 0)
    302 		thousands_sep = nl_langinfo (THOUSANDS_SEP);
    303 	      else
    304 		thousands_sep = nl_langinfo (MON_THOUSANDS_SEP);
    305 	      if (*thousands_sep == '\0')
    306 		grouping = NULL;
    307 	    }
    308 	}
    309     }
    310   else
    311 #elif defined USE_NL_LANGINFO
    312   if (info->group && !wide)
    313     {
    314       if (info->extra == 0)
    315 	grouping = nl_langinfo (GROUPING);
    316       else
    317 	grouping = nl_langinfo (MON_GROUPING);
    318 
    319       if (*grouping <= 0 || *grouping == CHAR_MAX)
    320 	grouping = NULL;
    321       else
    322 	{
    323 	  /* Figure out the thousands separator character.  */
    324 	  if (info->extra == 0)
    325 	    thousands_sep = nl_langinfo (THOUSANDS_SEP);
    326 	  else
    327 	    thousands_sep = nl_langinfo (MON_THOUSANDS_SEP);
    328 
    329 	  if (*thousands_sep == '\0')
    330 	    grouping = NULL;
    331 	}
    332     }
    333   else
    334 #elif defined USE_LOCALECONV
    335   if (info->group && !wide)
    336     {
    337       if (info->extra == 0)
    338 	grouping = lc->grouping;
    339       else
    340 	grouping = lc->mon_grouping;
    341 
    342       if (grouping == NULL || *grouping <= 0 || *grouping == CHAR_MAX)
    343 	grouping = NULL;
    344       else
    345 	{
    346 	  /* Figure out the thousands separator character.  */
    347 	  if (info->extra == 0)
    348 	    thousands_sep = lc->thousands_sep;
    349 	  else
    350 	    thousands_sep = lc->mon_thousands_sep;
    351 
    352 	  if (thousands_sep == NULL || *thousands_sep == '\0')
    353 	    grouping = NULL;
    354 	}
    355     }
    356   else
    357 #endif
    358     grouping = NULL;
    359   if (grouping != NULL && !wide)
    360     /* If we are printing multibyte characters and there is a
    361        multibyte representation for the thousands separator,
    362        we must ensure the wide character thousands separator
    363        is available, even if it is fake.  */
    364     thousands_sepwc = (wchar_t) 0xfffffffe;
    365 
    366   /* Fetch the argument value.	*/
    367     {
    368       memcpy (&fpnum, *(const void *const *) args[0], sizeof (fpnum));
    369 
    370       /* Check for special values: not a number or infinity.  */
    371       if (isnanq (fpnum))
    372 	{
    373 	  ieee854_float128 u = { .value = fpnum };
    374 	  is_neg = u.ieee.negative != 0;
    375 	  if (isupper (info->spec))
    376 	    {
    377 	      special = "NAN";
    378 	      wspecial = L_("NAN");
    379 	    }
    380 	  else
    381 	    {
    382 	      special = "nan";
    383 		wspecial = L_("nan");
    384 	    }
    385 	}
    386       else if (isinfq (fpnum))
    387 	{
    388 	  is_neg = fpnum < 0;
    389 	  if (isupper (info->spec))
    390 	    {
    391 	      special = "INF";
    392 	      wspecial = L_("INF");
    393 	    }
    394 	  else
    395 	    {
    396 	      special = "inf";
    397 	      wspecial = L_("inf");
    398 	    }
    399 	}
    400       else
    401 	{
    402 	  fracsize = mpn_extract_flt128 (fp_input,
    403 					 (sizeof (fp_input) /
    404 					  sizeof (fp_input[0])),
    405 					 &exponent, &is_neg, fpnum);
    406 	  to_shift = 1 + fracsize * BITS_PER_MP_LIMB - FLT128_MANT_DIG;
    407 	}
    408     }
    409 
    410   if (special)
    411     {
    412       int width = info->width;
    413 
    414       if (is_neg || info->showsign || info->space)
    415 	--width;
    416       width -= 3;
    417 
    418       if (!info->left && width > 0)
    419 	PADN (' ', width);
    420 
    421       if (is_neg)
    422 	outchar ('-');
    423       else if (info->showsign)
    424 	outchar ('+');
    425       else if (info->space)
    426 	outchar (' ');
    427 
    428       PRINT (special, wspecial, 3);
    429 
    430       if (info->left && width > 0)
    431 	PADN (' ', width);
    432 
    433       return done;
    434     }
    435 
    436 
    437   /* We need three multiprecision variables.  Now that we have the exponent
    438      of the number we can allocate the needed memory.  It would be more
    439      efficient to use variables of the fixed maximum size but because this
    440      would be really big it could lead to memory problems.  */
    441   {
    442     mp_size_t bignum_size = ((ABS (exponent) + BITS_PER_MP_LIMB - 1)
    443 			     / BITS_PER_MP_LIMB
    444 			     + (FLT128_MANT_DIG / BITS_PER_MP_LIMB > 2 ? 8 : 4))
    445 			    * sizeof (mp_limb_t);
    446     frac = (mp_limb_t *) alloca (bignum_size);
    447     tmp = (mp_limb_t *) alloca (bignum_size);
    448     scale = (mp_limb_t *) alloca (bignum_size);
    449   }
    450 
    451   /* We now have to distinguish between numbers with positive and negative
    452      exponents because the method used for the one is not applicable/efficient
    453      for the other.  */
    454   scalesize = 0;
    455   if (exponent > 2)
    456     {
    457       /* |FP| >= 8.0.  */
    458       int scaleexpo = 0;
    459       int explog = FLT128_MAX_10_EXP_LOG;
    460       int exp10 = 0;
    461       const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
    462       int cnt_h, cnt_l, i;
    463 
    464       if ((exponent + to_shift) % BITS_PER_MP_LIMB == 0)
    465 	{
    466 	  MPN_COPY_DECR (frac + (exponent + to_shift) / BITS_PER_MP_LIMB,
    467 			 fp_input, fracsize);
    468 	  fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB;
    469 	}
    470       else
    471 	{
    472 	  cy = mpn_lshift (frac + (exponent + to_shift) / BITS_PER_MP_LIMB,
    473 			   fp_input, fracsize,
    474 			   (exponent + to_shift) % BITS_PER_MP_LIMB);
    475 	  fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB;
    476 	  if (cy)
    477 	    frac[fracsize++] = cy;
    478 	}
    479       MPN_ZERO (frac, (exponent + to_shift) / BITS_PER_MP_LIMB);
    480 
    481       assert (powers > &_fpioconst_pow10[0]);
    482       do
    483 	{
    484 	  --powers;
    485 
    486 	  /* The number of the product of two binary numbers with n and m
    487 	     bits respectively has m+n or m+n-1 bits.	*/
    488 	  if (exponent >= scaleexpo + powers->p_expo - 1)
    489 	    {
    490 	      if (scalesize == 0)
    491 		{
    492 		  if (FLT128_MANT_DIG > _FPIO_CONST_OFFSET * BITS_PER_MP_LIMB)
    493 		    {
    494 #define _FPIO_CONST_SHIFT \
    495   (((FLT128_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB) \
    496    - _FPIO_CONST_OFFSET)
    497 		      /* 64bit const offset is not enough for
    498 			 IEEE quad long double.  */
    499 		      tmpsize = powers->arraysize + _FPIO_CONST_SHIFT;
    500 		      memcpy (tmp + _FPIO_CONST_SHIFT,
    501 			      &__tens[powers->arrayoff],
    502 			      tmpsize * sizeof (mp_limb_t));
    503 		      MPN_ZERO (tmp, _FPIO_CONST_SHIFT);
    504 		      /* Adjust exponent, as scaleexpo will be this much
    505 			 bigger too.  */
    506 		      exponent += _FPIO_CONST_SHIFT * BITS_PER_MP_LIMB;
    507 		    }
    508 		  else
    509 		    {
    510 		      tmpsize = powers->arraysize;
    511 		      memcpy (tmp, &__tens[powers->arrayoff],
    512 			      tmpsize * sizeof (mp_limb_t));
    513 		    }
    514 		}
    515 	      else
    516 		{
    517 		  cy = mpn_mul (tmp, scale, scalesize,
    518 				&__tens[powers->arrayoff
    519 					+ _FPIO_CONST_OFFSET],
    520 				powers->arraysize - _FPIO_CONST_OFFSET);
    521 		  tmpsize = scalesize + powers->arraysize - _FPIO_CONST_OFFSET;
    522 		  if (cy == 0)
    523 		    --tmpsize;
    524 		}
    525 
    526 	      if (MPN_GE (frac, tmp))
    527 		{
    528 		  int cnt;
    529 		  MPN_ASSIGN (scale, tmp);
    530 		  count_leading_zeros (cnt, scale[scalesize - 1]);
    531 		  scaleexpo = (scalesize - 2) * BITS_PER_MP_LIMB - cnt - 1;
    532 		  exp10 |= 1 << explog;
    533 		}
    534 	    }
    535 	  --explog;
    536 	}
    537       while (powers > &_fpioconst_pow10[0]);
    538       exponent = exp10;
    539 
    540       /* Optimize number representations.  We want to represent the numbers
    541 	 with the lowest number of bytes possible without losing any
    542 	 bytes. Also the highest bit in the scaling factor has to be set
    543 	 (this is a requirement of the MPN division routines).  */
    544       if (scalesize > 0)
    545 	{
    546 	  /* Determine minimum number of zero bits at the end of
    547 	     both numbers.  */
    548 	  for (i = 0; scale[i] == 0 && frac[i] == 0; i++)
    549 	    ;
    550 
    551 	  /* Determine number of bits the scaling factor is misplaced.	*/
    552 	  count_leading_zeros (cnt_h, scale[scalesize - 1]);
    553 
    554 	  if (cnt_h == 0)
    555 	    {
    556 	      /* The highest bit of the scaling factor is already set.	So
    557 		 we only have to remove the trailing empty limbs.  */
    558 	      if (i > 0)
    559 		{
    560 		  MPN_COPY_INCR (scale, scale + i, scalesize - i);
    561 		  scalesize -= i;
    562 		  MPN_COPY_INCR (frac, frac + i, fracsize - i);
    563 		  fracsize -= i;
    564 		}
    565 	    }
    566 	  else
    567 	    {
    568 	      if (scale[i] != 0)
    569 		{
    570 		  count_trailing_zeros (cnt_l, scale[i]);
    571 		  if (frac[i] != 0)
    572 		    {
    573 		      int cnt_l2;
    574 		      count_trailing_zeros (cnt_l2, frac[i]);
    575 		      if (cnt_l2 < cnt_l)
    576 			cnt_l = cnt_l2;
    577 		    }
    578 		}
    579 	      else
    580 		count_trailing_zeros (cnt_l, frac[i]);
    581 
    582 	      /* Now shift the numbers to their optimal position.  */
    583 	      if (i == 0 && BITS_PER_MP_LIMB - cnt_h > cnt_l)
    584 		{
    585 		  /* We cannot save any memory.	 So just roll both numbers
    586 		     so that the scaling factor has its highest bit set.  */
    587 
    588 		  (void) mpn_lshift (scale, scale, scalesize, cnt_h);
    589 		  cy = mpn_lshift (frac, frac, fracsize, cnt_h);
    590 		  if (cy != 0)
    591 		    frac[fracsize++] = cy;
    592 		}
    593 	      else if (BITS_PER_MP_LIMB - cnt_h <= cnt_l)
    594 		{
    595 		  /* We can save memory by removing the trailing zero limbs
    596 		     and by packing the non-zero limbs which gain another
    597 		     free one. */
    598 
    599 		  (void) mpn_rshift (scale, scale + i, scalesize - i,
    600 				     BITS_PER_MP_LIMB - cnt_h);
    601 		  scalesize -= i + 1;
    602 		  (void) mpn_rshift (frac, frac + i, fracsize - i,
    603 				     BITS_PER_MP_LIMB - cnt_h);
    604 		  fracsize -= frac[fracsize - i - 1] == 0 ? i + 1 : i;
    605 		}
    606 	      else
    607 		{
    608 		  /* We can only save the memory of the limbs which are zero.
    609 		     The non-zero parts occupy the same number of limbs.  */
    610 
    611 		  (void) mpn_rshift (scale, scale + (i - 1),
    612 				     scalesize - (i - 1),
    613 				     BITS_PER_MP_LIMB - cnt_h);
    614 		  scalesize -= i;
    615 		  (void) mpn_rshift (frac, frac + (i - 1),
    616 				     fracsize - (i - 1),
    617 				     BITS_PER_MP_LIMB - cnt_h);
    618 		  fracsize -= frac[fracsize - (i - 1) - 1] == 0 ? i : i - 1;
    619 		}
    620 	    }
    621 	}
    622     }
    623   else if (exponent < 0)
    624     {
    625       /* |FP| < 1.0.  */
    626       int exp10 = 0;
    627       int explog = FLT128_MAX_10_EXP_LOG;
    628       const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
    629 
    630       /* Now shift the input value to its right place.	*/
    631       cy = mpn_lshift (frac, fp_input, fracsize, to_shift);
    632       frac[fracsize++] = cy;
    633       assert (cy == 1 || (frac[fracsize - 2] == 0 && frac[0] == 0));
    634 
    635       expsign = 1;
    636       exponent = -exponent;
    637 
    638       assert (powers != &_fpioconst_pow10[0]);
    639       do
    640 	{
    641 	  --powers;
    642 
    643 	  if (exponent >= powers->m_expo)
    644 	    {
    645 	      int i, incr, cnt_h, cnt_l;
    646 	      mp_limb_t topval[2];
    647 
    648 	      /* The mpn_mul function expects the first argument to be
    649 		 bigger than the second.  */
    650 	      if (fracsize < powers->arraysize - _FPIO_CONST_OFFSET)
    651 		cy = mpn_mul (tmp, &__tens[powers->arrayoff
    652 					   + _FPIO_CONST_OFFSET],
    653 			      powers->arraysize - _FPIO_CONST_OFFSET,
    654 			      frac, fracsize);
    655 	      else
    656 		cy = mpn_mul (tmp, frac, fracsize,
    657 			      &__tens[powers->arrayoff + _FPIO_CONST_OFFSET],
    658 			      powers->arraysize - _FPIO_CONST_OFFSET);
    659 	      tmpsize = fracsize + powers->arraysize - _FPIO_CONST_OFFSET;
    660 	      if (cy == 0)
    661 		--tmpsize;
    662 
    663 	      count_leading_zeros (cnt_h, tmp[tmpsize - 1]);
    664 	      incr = (tmpsize - fracsize) * BITS_PER_MP_LIMB
    665 		     + BITS_PER_MP_LIMB - 1 - cnt_h;
    666 
    667 	      assert (incr <= powers->p_expo);
    668 
    669 	      /* If we increased the exponent by exactly 3 we have to test
    670 		 for overflow.	This is done by comparing with 10 shifted
    671 		 to the right position.	 */
    672 	      if (incr == exponent + 3)
    673 		{
    674 		  if (cnt_h <= BITS_PER_MP_LIMB - 4)
    675 		    {
    676 		      topval[0] = 0;
    677 		      topval[1]
    678 			= ((mp_limb_t) 10) << (BITS_PER_MP_LIMB - 4 - cnt_h);
    679 		    }
    680 		  else
    681 		    {
    682 		      topval[0] = ((mp_limb_t) 10) << (BITS_PER_MP_LIMB - 4);
    683 		      topval[1] = 0;
    684 		      (void) mpn_lshift (topval, topval, 2,
    685 					 BITS_PER_MP_LIMB - cnt_h);
    686 		    }
    687 		}
    688 
    689 	      /* We have to be careful when multiplying the last factor.
    690 		 If the result is greater than 1.0 be have to test it
    691 		 against 10.0.  If it is greater or equal to 10.0 the
    692 		 multiplication was not valid.  This is because we cannot
    693 		 determine the number of bits in the result in advance.  */
    694 	      if (incr < exponent + 3
    695 		  || (incr == exponent + 3 &&
    696 		      (tmp[tmpsize - 1] < topval[1]
    697 		       || (tmp[tmpsize - 1] == topval[1]
    698 			   && tmp[tmpsize - 2] < topval[0]))))
    699 		{
    700 		  /* The factor is right.  Adapt binary and decimal
    701 		     exponents.	 */
    702 		  exponent -= incr;
    703 		  exp10 |= 1 << explog;
    704 
    705 		  /* If this factor yields a number greater or equal to
    706 		     1.0, we must not shift the non-fractional digits down. */
    707 		  if (exponent < 0)
    708 		    cnt_h += -exponent;
    709 
    710 		  /* Now we optimize the number representation.	 */
    711 		  for (i = 0; tmp[i] == 0; ++i);
    712 		  if (cnt_h == BITS_PER_MP_LIMB - 1)
    713 		    {
    714 		      MPN_COPY (frac, tmp + i, tmpsize - i);
    715 		      fracsize = tmpsize - i;
    716 		    }
    717 		  else
    718 		    {
    719 		      count_trailing_zeros (cnt_l, tmp[i]);
    720 
    721 		      /* Now shift the numbers to their optimal position.  */
    722 		      if (i == 0 && BITS_PER_MP_LIMB - 1 - cnt_h > cnt_l)
    723 			{
    724 			  /* We cannot save any memory.	 Just roll the
    725 			     number so that the leading digit is in a
    726 			     separate limb.  */
    727 
    728 			  cy = mpn_lshift (frac, tmp, tmpsize, cnt_h + 1);
    729 			  fracsize = tmpsize + 1;
    730 			  frac[fracsize - 1] = cy;
    731 			}
    732 		      else if (BITS_PER_MP_LIMB - 1 - cnt_h <= cnt_l)
    733 			{
    734 			  (void) mpn_rshift (frac, tmp + i, tmpsize - i,
    735 					     BITS_PER_MP_LIMB - 1 - cnt_h);
    736 			  fracsize = tmpsize - i;
    737 			}
    738 		      else
    739 			{
    740 			  /* We can only save the memory of the limbs which
    741 			     are zero.	The non-zero parts occupy the same
    742 			     number of limbs.  */
    743 
    744 			  (void) mpn_rshift (frac, tmp + (i - 1),
    745 					     tmpsize - (i - 1),
    746 					     BITS_PER_MP_LIMB - 1 - cnt_h);
    747 			  fracsize = tmpsize - (i - 1);
    748 			}
    749 		    }
    750 		}
    751 	    }
    752 	  --explog;
    753 	}
    754       while (powers != &_fpioconst_pow10[1] && exponent > 0);
    755       /* All factors but 10^-1 are tested now.	*/
    756       if (exponent > 0)
    757 	{
    758 	  int cnt_l;
    759 
    760 	  cy = mpn_mul_1 (tmp, frac, fracsize, 10);
    761 	  tmpsize = fracsize;
    762 	  assert (cy == 0 || tmp[tmpsize - 1] < 20);
    763 
    764 	  count_trailing_zeros (cnt_l, tmp[0]);
    765 	  if (cnt_l < MIN (4, exponent))
    766 	    {
    767 	      cy = mpn_lshift (frac, tmp, tmpsize,
    768 			       BITS_PER_MP_LIMB - MIN (4, exponent));
    769 	      if (cy != 0)
    770 		frac[tmpsize++] = cy;
    771 	    }
    772 	  else
    773 	    (void) mpn_rshift (frac, tmp, tmpsize, MIN (4, exponent));
    774 	  fracsize = tmpsize;
    775 	  exp10 |= 1;
    776 	  assert (frac[fracsize - 1] < 10);
    777 	}
    778       exponent = exp10;
    779     }
    780   else
    781     {
    782       /* This is a special case.  We don't need a factor because the
    783 	 numbers are in the range of 1.0 <= |fp| < 8.0.  We simply
    784 	 shift it to the right place and divide it by 1.0 to get the
    785 	 leading digit.	 (Of course this division is not really made.)	*/
    786       assert (0 <= exponent && exponent < 3 &&
    787 	      exponent + to_shift < BITS_PER_MP_LIMB);
    788 
    789       /* Now shift the input value to its right place.	*/
    790       cy = mpn_lshift (frac, fp_input, fracsize, (exponent + to_shift));
    791       frac[fracsize++] = cy;
    792       exponent = 0;
    793     }
    794 
    795   {
    796     int width = info->width;
    797     wchar_t *wstartp, *wcp;
    798     size_t chars_needed;
    799     int expscale;
    800     int intdig_max, intdig_no = 0;
    801     int fracdig_min;
    802     int fracdig_max;
    803     int dig_max;
    804     int significant;
    805     int ngroups = 0;
    806     char spec = tolower (info->spec);
    807 
    808     if (spec == 'e')
    809       {
    810 	type = info->spec;
    811 	intdig_max = 1;
    812 	fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
    813 	chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4;
    814 	/*	       d   .	 ddd	     e	 +-  ddd  */
    815 	dig_max = __INT_MAX__;		/* Unlimited.  */
    816 	significant = 1;		/* Does not matter here.  */
    817       }
    818     else if (spec == 'f')
    819       {
    820 	type = 'f';
    821 	fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
    822 	dig_max = __INT_MAX__;		/* Unlimited.  */
    823 	significant = 1;		/* Does not matter here.  */
    824 	if (expsign == 0)
    825 	  {
    826 	    intdig_max = exponent + 1;
    827 	    /* This can be really big!	*/  /* XXX Maybe malloc if too big? */
    828 	    chars_needed = (size_t) exponent + 1 + 1 + (size_t) fracdig_max;
    829 	  }
    830 	else
    831 	  {
    832 	    intdig_max = 1;
    833 	    chars_needed = 1 + 1 + (size_t) fracdig_max;
    834 	  }
    835       }
    836     else
    837       {
    838 	dig_max = info->prec < 0 ? 6 : (info->prec == 0 ? 1 : info->prec);
    839 	if ((expsign == 0 && exponent >= dig_max)
    840 	    || (expsign != 0 && exponent > 4))
    841 	  {
    842 	    if ('g' - 'G' == 'e' - 'E')
    843 	      type = 'E' + (info->spec - 'G');
    844 	    else
    845 	      type = isupper (info->spec) ? 'E' : 'e';
    846 	    fracdig_max = dig_max - 1;
    847 	    intdig_max = 1;
    848 	    chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4;
    849 	  }
    850 	else
    851 	  {
    852 	    type = 'f';
    853 	    intdig_max = expsign == 0 ? exponent + 1 : 0;
    854 	    fracdig_max = dig_max - intdig_max;
    855 	    /* We need space for the significant digits and perhaps
    856 	       for leading zeros when < 1.0.  The number of leading
    857 	       zeros can be as many as would be required for
    858 	       exponential notation with a negative two-digit
    859 	       exponent, which is 4.  */
    860 	    chars_needed = (size_t) dig_max + 1 + 4;
    861 	  }
    862 	fracdig_min = info->alt ? fracdig_max : 0;
    863 	significant = 0;		/* We count significant digits.	 */
    864       }
    865 
    866     if (grouping)
    867       {
    868 	/* Guess the number of groups we will make, and thus how
    869 	   many spaces we need for separator characters.  */
    870 	ngroups = guess_grouping (intdig_max, grouping);
    871 	/* Allocate one more character in case rounding increases the
    872 	   number of groups.  */
    873 	chars_needed += ngroups + 1;
    874       }
    875 
    876     /* Allocate buffer for output.  We need two more because while rounding
    877        it is possible that we need two more characters in front of all the
    878        other output.  If the amount of memory we have to allocate is too
    879        large use `malloc' instead of `alloca'.  */
    880     if (__builtin_expect (chars_needed >= (size_t) -1 / sizeof (wchar_t) - 2
    881 			  || chars_needed < fracdig_max, 0))
    882       {
    883 	/* Some overflow occurred.  */
    884 #if defined HAVE_ERRNO_H && defined ERANGE
    885 	errno = ERANGE;
    886 #endif
    887 	return -1;
    888       }
    889     size_t wbuffer_to_alloc = (2 + chars_needed) * sizeof (wchar_t);
    890     buffer_malloced = wbuffer_to_alloc >= 4096;
    891     if (__builtin_expect (buffer_malloced, 0))
    892       {
    893 	wbuffer = (wchar_t *) malloc (wbuffer_to_alloc);
    894 	if (wbuffer == NULL)
    895 	  /* Signal an error to the caller.  */
    896 	  return -1;
    897       }
    898     else
    899       wbuffer = (wchar_t *) alloca (wbuffer_to_alloc);
    900     wcp = wstartp = wbuffer + 2;	/* Let room for rounding.  */
    901 
    902     /* Do the real work: put digits in allocated buffer.  */
    903     if (expsign == 0 || type != 'f')
    904       {
    905 	assert (expsign == 0 || intdig_max == 1);
    906 	while (intdig_no < intdig_max)
    907 	  {
    908 	    ++intdig_no;
    909 	    *wcp++ = hack_digit ();
    910 	  }
    911 	significant = 1;
    912 	if (info->alt
    913 	    || fracdig_min > 0
    914 	    || (fracdig_max > 0 && (fracsize > 1 || frac[0] != 0)))
    915 	  *wcp++ = decimalwc;
    916       }
    917     else
    918       {
    919 	/* |fp| < 1.0 and the selected type is 'f', so put "0."
    920 	   in the buffer.  */
    921 	*wcp++ = L_('0');
    922 	--exponent;
    923 	*wcp++ = decimalwc;
    924       }
    925 
    926     /* Generate the needed number of fractional digits.	 */
    927     int fracdig_no = 0;
    928     int added_zeros = 0;
    929     while (fracdig_no < fracdig_min + added_zeros
    930 	   || (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
    931       {
    932 	++fracdig_no;
    933 	*wcp = hack_digit ();
    934 	if (*wcp++ != L_('0'))
    935 	  significant = 1;
    936 	else if (significant == 0)
    937 	  {
    938 	    ++fracdig_max;
    939 	    if (fracdig_min > 0)
    940 	      ++added_zeros;
    941 	  }
    942       }
    943 
    944     /* Do rounding.  */
    945     last_digit = wcp[-1] != decimalwc ? wcp[-1] : wcp[-2];
    946     next_digit =hack_digit ();
    947 
    948     if (next_digit != L_('0') && next_digit != L_('5'))
    949       more_bits = true;
    950     else if (fracsize == 1 && frac[0] == 0)
    951       /* Rest of the number is zero.  */
    952       more_bits = false;
    953     else if (scalesize == 0)
    954       {
    955 	/* Here we have to see whether all limbs are zero since no
    956 	   normalization happened.  */
    957 	size_t lcnt = fracsize;
    958 	while (lcnt >= 1 && frac[lcnt - 1] == 0)
    959 	  --lcnt;
    960 	more_bits = lcnt > 0;
    961       }
    962     else
    963       more_bits = true;
    964 
    965 #ifdef HAVE_FENV_H
    966     int rounding_mode = get_rounding_mode ();
    967     if (round_away (is_neg, (last_digit - L_('0')) & 1, next_digit >= L_('5'),
    968 		    more_bits, rounding_mode))
    969       {
    970 	wchar_t *wtp = wcp;
    971 
    972 	if (fracdig_no > 0)
    973 	  {
    974 	    /* Process fractional digits.  Terminate if not rounded or
    975 	       radix character is reached.  */
    976 	    int removed = 0;
    977 	    while (*--wtp != decimalwc && *wtp == L_('9'))
    978 	      {
    979 		*wtp = L_('0');
    980 		++removed;
    981 	      }
    982 	    if (removed == fracdig_min && added_zeros > 0)
    983 	      --added_zeros;
    984 	    if (*wtp != decimalwc)
    985 	      /* Round up.  */
    986 	      (*wtp)++;
    987 	    else if (__builtin_expect (spec == 'g' && type == 'f' && info->alt
    988 				       && wtp == wstartp + 1
    989 				       && wstartp[0] == L_('0'),
    990 				       0))
    991 	      /* This is a special case: the rounded number is 1.0,
    992 		 the format is 'g' or 'G', and the alternative format
    993 		 is selected.  This means the result must be "1.".  */
    994 	      --added_zeros;
    995 	  }
    996 
    997 	if (fracdig_no == 0 || *wtp == decimalwc)
    998 	  {
    999 	    /* Round the integer digits.  */
   1000 	    if (*(wtp - 1) == decimalwc)
   1001 	      --wtp;
   1002 
   1003 	    while (--wtp >= wstartp && *wtp == L_('9'))
   1004 	      *wtp = L_('0');
   1005 
   1006 	    if (wtp >= wstartp)
   1007 	      /* Round up.  */
   1008 	      (*wtp)++;
   1009 	    else
   1010 	      /* It is more critical.  All digits were 9's.  */
   1011 	      {
   1012 		if (type != 'f')
   1013 		  {
   1014 		    *wstartp = '1';
   1015 		    exponent += expsign == 0 ? 1 : -1;
   1016 
   1017 		    /* The above exponent adjustment could lead to 1.0e-00,
   1018 		       e.g. for 0.999999999.  Make sure exponent 0 always
   1019 		       uses + sign.  */
   1020 		    if (exponent == 0)
   1021 		      expsign = 0;
   1022 		  }
   1023 		else if (intdig_no == dig_max)
   1024 		  {
   1025 		    /* This is the case where for type %g the number fits
   1026 		       really in the range for %f output but after rounding
   1027 		       the number of digits is too big.	 */
   1028 		    *--wstartp = decimalwc;
   1029 		    *--wstartp = L_('1');
   1030 
   1031 		    if (info->alt || fracdig_no > 0)
   1032 		      {
   1033 			/* Overwrite the old radix character.  */
   1034 			wstartp[intdig_no + 2] = L_('0');
   1035 			++fracdig_no;
   1036 		      }
   1037 
   1038 		    fracdig_no += intdig_no;
   1039 		    intdig_no = 1;
   1040 		    fracdig_max = intdig_max - intdig_no;
   1041 		    ++exponent;
   1042 		    /* Now we must print the exponent.	*/
   1043 		    type = isupper (info->spec) ? 'E' : 'e';
   1044 		  }
   1045 		else
   1046 		  {
   1047 		    /* We can simply add another another digit before the
   1048 		       radix.  */
   1049 		    *--wstartp = L_('1');
   1050 		    ++intdig_no;
   1051 		  }
   1052 
   1053 		/* While rounding the number of digits can change.
   1054 		   If the number now exceeds the limits remove some
   1055 		   fractional digits.  */
   1056 		if (intdig_no + fracdig_no > dig_max)
   1057 		  {
   1058 		    wcp -= intdig_no + fracdig_no - dig_max;
   1059 		    fracdig_no -= intdig_no + fracdig_no - dig_max;
   1060 		  }
   1061 	      }
   1062 	  }
   1063       }
   1064 #endif
   1065 
   1066     /* Now remove unnecessary '0' at the end of the string.  */
   1067     while (fracdig_no > fracdig_min + added_zeros && *(wcp - 1) == L_('0'))
   1068       {
   1069 	--wcp;
   1070 	--fracdig_no;
   1071       }
   1072     /* If we eliminate all fractional digits we perhaps also can remove
   1073        the radix character.  */
   1074     if (fracdig_no == 0 && !info->alt && *(wcp - 1) == decimalwc)
   1075       --wcp;
   1076 
   1077     if (grouping)
   1078       {
   1079 	/* Rounding might have changed the number of groups.  We allocated
   1080 	   enough memory but we need here the correct number of groups.  */
   1081 	if (intdig_no != intdig_max)
   1082 	  ngroups = guess_grouping (intdig_no, grouping);
   1083 
   1084 	/* Add in separator characters, overwriting the same buffer.  */
   1085 	wcp = group_number (wstartp, wcp, intdig_no, grouping, thousands_sepwc,
   1086 			    ngroups);
   1087       }
   1088 
   1089     /* Write the exponent if it is needed.  */
   1090     if (type != 'f')
   1091       {
   1092 	if (__builtin_expect (expsign != 0 && exponent == 4 && spec == 'g', 0))
   1093 	  {
   1094 	    /* This is another special case.  The exponent of the number is
   1095 	       really smaller than -4, which requires the 'e'/'E' format.
   1096 	       But after rounding the number has an exponent of -4.  */
   1097 	    assert (wcp >= wstartp + 1);
   1098 	    assert (wstartp[0] == L_('1'));
   1099 	    memcpy (wstartp, L_("0.0001"), 6 * sizeof (wchar_t));
   1100 	    wstartp[1] = decimalwc;
   1101 	    if (wcp >= wstartp + 2)
   1102 	      {
   1103 		size_t cnt;
   1104 		for (cnt = 0; cnt < wcp - (wstartp + 2); cnt++)
   1105 		  wstartp[6 + cnt] = L_('0');
   1106 		wcp += 4;
   1107 	      }
   1108 	    else
   1109 	      wcp += 5;
   1110 	  }
   1111 	else
   1112 	  {
   1113 	    *wcp++ = (wchar_t) type;
   1114 	    *wcp++ = expsign ? L_('-') : L_('+');
   1115 
   1116 	    /* Find the magnitude of the exponent.	*/
   1117 	    expscale = 10;
   1118 	    while (expscale <= exponent)
   1119 	      expscale *= 10;
   1120 
   1121 	    if (exponent < 10)
   1122 	      /* Exponent always has at least two digits.  */
   1123 	      *wcp++ = L_('0');
   1124 	    else
   1125 	      do
   1126 		{
   1127 		  expscale /= 10;
   1128 		  *wcp++ = L_('0') + (exponent / expscale);
   1129 		  exponent %= expscale;
   1130 		}
   1131 	      while (expscale > 10);
   1132 	    *wcp++ = L_('0') + exponent;
   1133 	  }
   1134       }
   1135 
   1136     /* Compute number of characters which must be filled with the padding
   1137        character.  */
   1138     if (is_neg || info->showsign || info->space)
   1139       --width;
   1140     width -= wcp - wstartp;
   1141 
   1142     if (!info->left && info->pad != '0' && width > 0)
   1143       PADN (info->pad, width);
   1144 
   1145     if (is_neg)
   1146       outchar ('-');
   1147     else if (info->showsign)
   1148       outchar ('+');
   1149     else if (info->space)
   1150       outchar (' ');
   1151 
   1152     if (!info->left && info->pad == '0' && width > 0)
   1153       PADN ('0', width);
   1154 
   1155     {
   1156       char *buffer = NULL;
   1157       char *buffer_end __attribute__((__unused__)) = NULL;
   1158       char *cp = NULL;
   1159       char *tmpptr;
   1160 
   1161       if (! wide)
   1162 	{
   1163 	  /* Create the single byte string.  */
   1164 	  size_t decimal_len;
   1165 	  size_t thousands_sep_len;
   1166 	  wchar_t *copywc;
   1167 #ifdef USE_I18N_NUMBER_H
   1168 	  size_t factor = (info->i18n
   1169 			   ? nl_langinfo_wc (_NL_CTYPE_MB_CUR_MAX)
   1170 			   : 1);
   1171 #else
   1172 	  size_t factor = 1;
   1173 #endif
   1174 
   1175 	  decimal_len = strlen (decimal);
   1176 
   1177 	  if (thousands_sep == NULL)
   1178 	    thousands_sep_len = 0;
   1179 	  else
   1180 	    thousands_sep_len = strlen (thousands_sep);
   1181 
   1182 	  size_t nbuffer = (2 + chars_needed * factor + decimal_len
   1183 			    + ngroups * thousands_sep_len);
   1184 	  if (__builtin_expect (buffer_malloced, 0))
   1185 	    {
   1186 	      buffer = (char *) malloc (nbuffer);
   1187 	      if (buffer == NULL)
   1188 		{
   1189 		  /* Signal an error to the caller.  */
   1190 		  free (wbuffer);
   1191 		  return -1;
   1192 		}
   1193 	    }
   1194 	  else
   1195 	    buffer = (char *) alloca (nbuffer);
   1196 	  buffer_end = buffer + nbuffer;
   1197 
   1198 	  /* Now copy the wide character string.  Since the character
   1199 	     (except for the decimal point and thousands separator) must
   1200 	     be coming from the ASCII range we can esily convert the
   1201 	     string without mapping tables.  */
   1202 	  for (cp = buffer, copywc = wstartp; copywc < wcp; ++copywc)
   1203 	    if (*copywc == decimalwc)
   1204 	      memcpy (cp, decimal, decimal_len), cp += decimal_len;
   1205 	    else if (*copywc == thousands_sepwc)
   1206 	      memcpy (cp, thousands_sep, thousands_sep_len), cp += thousands_sep_len;
   1207 	    else
   1208 	      *cp++ = (char) *copywc;
   1209 	}
   1210 
   1211       tmpptr = buffer;
   1212 #if USE_I18N_NUMBER_H
   1213       if (__builtin_expect (info->i18n, 0))
   1214 	{
   1215 	  tmpptr = _i18n_number_rewrite (tmpptr, cp, buffer_end);
   1216 	  cp = buffer_end;
   1217 	  assert ((uintptr_t) buffer <= (uintptr_t) tmpptr);
   1218 	  assert ((uintptr_t) tmpptr < (uintptr_t) buffer_end);
   1219 	}
   1220 #endif
   1221 
   1222       PRINT (tmpptr, wstartp, wide ? wcp - wstartp : cp - tmpptr);
   1223 
   1224       /* Free the memory if necessary.  */
   1225       if (__builtin_expect (buffer_malloced, 0))
   1226 	{
   1227 	  free (buffer);
   1228 	  free (wbuffer);
   1229 	}
   1230     }
   1231 
   1232     if (info->left && width > 0)
   1233       PADN (info->pad, width);
   1234   }
   1235   return done;
   1236 }
   1237 
   1238 /* Return the number of extra grouping characters that will be inserted
   1240    into a number with INTDIG_MAX integer digits.  */
   1241 
   1242 static unsigned int
   1243 guess_grouping (unsigned int intdig_max, const char *grouping)
   1244 {
   1245   unsigned int groups;
   1246 
   1247   /* We treat all negative values like CHAR_MAX.  */
   1248 
   1249   if (*grouping == CHAR_MAX || *grouping <= 0)
   1250     /* No grouping should be done.  */
   1251     return 0;
   1252 
   1253   groups = 0;
   1254   while (intdig_max > (unsigned int) *grouping)
   1255     {
   1256       ++groups;
   1257       intdig_max -= *grouping++;
   1258 
   1259       if (*grouping == CHAR_MAX
   1260 #if CHAR_MIN < 0
   1261 	  || *grouping < 0
   1262 #endif
   1263 	  )
   1264 	/* No more grouping should be done.  */
   1265 	break;
   1266       else if (*grouping == 0)
   1267 	{
   1268 	  /* Same grouping repeats.  */
   1269 	  groups += (intdig_max - 1) / grouping[-1];
   1270 	  break;
   1271 	}
   1272     }
   1273 
   1274   return groups;
   1275 }
   1276 
   1277 /* Group the INTDIG_NO integer digits of the number in [BUF,BUFEND).
   1278    There is guaranteed enough space past BUFEND to extend it.
   1279    Return the new end of buffer.  */
   1280 
   1281 static wchar_t *
   1282 group_number (wchar_t *buf, wchar_t *bufend, unsigned int intdig_no,
   1283 	      const char *grouping, wchar_t thousands_sep, int ngroups)
   1284 {
   1285   wchar_t *p;
   1286 
   1287   if (ngroups == 0)
   1288     return bufend;
   1289 
   1290   /* Move the fractional part down.  */
   1291   memmove (buf + intdig_no + ngroups, buf + intdig_no,
   1292 	   (bufend - (buf + intdig_no)) * sizeof (wchar_t));
   1293 
   1294   p = buf + intdig_no + ngroups - 1;
   1295   do
   1296     {
   1297       unsigned int len = *grouping++;
   1298       do
   1299 	*p-- = buf[--intdig_no];
   1300       while (--len > 0);
   1301       *p-- = thousands_sep;
   1302 
   1303       if (*grouping == CHAR_MAX
   1304 #if CHAR_MIN < 0
   1305 	  || *grouping < 0
   1306 #endif
   1307 	  )
   1308 	/* No more grouping should be done.  */
   1309 	break;
   1310       else if (*grouping == 0)
   1311 	/* Same grouping repeats.  */
   1312 	--grouping;
   1313     } while (intdig_no > (unsigned int) *grouping);
   1314 
   1315   /* Copy the remaining ungrouped digits.  */
   1316   do
   1317     *p-- = buf[--intdig_no];
   1318   while (p > buf);
   1319 
   1320   return bufend + ngroups;
   1321 }
   1322