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