15af32e75SAxel Dörfler /* Print floating point number in hexadecimal notation according to ISO C99.
2294818c5SAlex Smith Copyright (C) 1997-2002,2004,2006 Free Software Foundation, Inc.
35af32e75SAxel Dörfler This file is part of the GNU C Library.
45af32e75SAxel Dörfler Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
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 #include <ctype.h>
225af32e75SAxel Dörfler #include <ieee754.h>
235af32e75SAxel Dörfler #include <math.h>
245af32e75SAxel Dörfler #include <printf.h>
255af32e75SAxel Dörfler #include <stdlib.h>
265af32e75SAxel Dörfler #include <stdio.h>
275af32e75SAxel Dörfler #include <string.h>
285af32e75SAxel Dörfler #include <wchar.h>
295af32e75SAxel Dörfler #include "_itoa.h"
305af32e75SAxel Dörfler #include "_itowa.h"
315af32e75SAxel Dörfler #include <locale/localeinfo.h>
325af32e75SAxel Dörfler
335af32e75SAxel Dörfler /* #define NDEBUG 1*/ /* Undefine this for debugging assertions. */
345af32e75SAxel Dörfler #include <assert.h>
355af32e75SAxel Dörfler
36d1716b27SOliver Tappe int __printf_fphex (FILE *fp, const struct printf_info *info,
37d1716b27SOliver Tappe const void *const *args);
38d1716b27SOliver Tappe
395af32e75SAxel Dörfler /* This defines make it possible to use the same code for GNU C library and
405af32e75SAxel Dörfler the GNU I/O library. */
415af32e75SAxel Dörfler #ifdef USE_IN_LIBIO
425af32e75SAxel Dörfler # include <libioP.h>
435af32e75SAxel Dörfler # define PUT(f, s, n) _IO_sputn (f, s, n)
445af32e75SAxel Dörfler # define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n))
455af32e75SAxel Dörfler /* We use this file GNU C library and GNU I/O library. So make
465af32e75SAxel Dörfler names equal. */
475af32e75SAxel Dörfler # undef putc
485af32e75SAxel Dörfler # define putc(c, f) (wide \
495af32e75SAxel Dörfler ? (int)_IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f))
505af32e75SAxel Dörfler # define size_t _IO_size_t
515af32e75SAxel Dörfler # define FILE _IO_FILE
525af32e75SAxel Dörfler #else /* ! USE_IN_LIBIO */
535af32e75SAxel Dörfler # define PUT(f, s, n) fwrite (s, 1, n, f)
545af32e75SAxel Dörfler # define PAD(f, c, n) __printf_pad (f, c, n)
555af32e75SAxel Dörfler ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c. */
565af32e75SAxel Dörfler #endif /* USE_IN_LIBIO */
577e8263e5SAugustin Cavalier
585af32e75SAxel Dörfler /* Macros for doing the actual output. */
595af32e75SAxel Dörfler
605af32e75SAxel Dörfler #define outchar(ch) \
615af32e75SAxel Dörfler do \
625af32e75SAxel Dörfler { \
635af32e75SAxel Dörfler register const int outc = (ch); \
645af32e75SAxel Dörfler if (putc (outc, fp) == EOF) \
655af32e75SAxel Dörfler return -1; \
665af32e75SAxel Dörfler ++done; \
675af32e75SAxel Dörfler } while (0)
685af32e75SAxel Dörfler
695af32e75SAxel Dörfler #define PRINT(ptr, wptr, len) \
705af32e75SAxel Dörfler do \
715af32e75SAxel Dörfler { \
725af32e75SAxel Dörfler register size_t outlen = (len); \
735af32e75SAxel Dörfler if (wide) \
745af32e75SAxel Dörfler while (outlen-- > 0) \
755af32e75SAxel Dörfler outchar (*wptr++); \
765af32e75SAxel Dörfler else \
775af32e75SAxel Dörfler while (outlen-- > 0) \
785af32e75SAxel Dörfler outchar (*ptr++); \
795af32e75SAxel Dörfler } while (0)
805af32e75SAxel Dörfler
815af32e75SAxel Dörfler #define PADN(ch, len) \
825af32e75SAxel Dörfler do \
835af32e75SAxel Dörfler { \
845af32e75SAxel Dörfler if (PAD (fp, ch, len) != len) \
855af32e75SAxel Dörfler return -1; \
865af32e75SAxel Dörfler done += len; \
875af32e75SAxel Dörfler } \
885af32e75SAxel Dörfler while (0)
895af32e75SAxel Dörfler
905af32e75SAxel Dörfler #ifndef MIN
915af32e75SAxel Dörfler # define MIN(a,b) ((a)<(b)?(a):(b))
925af32e75SAxel Dörfler #endif
937e8263e5SAugustin Cavalier
945af32e75SAxel Dörfler
95294818c5SAlex Smith
965ffbe7d7SAugustin Cavalier #if defined(__x86_64__) || defined(__i386__)
97294818c5SAlex Smith
98294818c5SAlex Smith /* sysdeps/x86_64/fpu/printf_fphex.c */
99294818c5SAlex Smith
100294818c5SAlex Smith #ifndef LONG_DOUBLE_DENORM_BIAS
101294818c5SAlex Smith # define LONG_DOUBLE_DENORM_BIAS (IEEE854_LONG_DOUBLE_BIAS - 1)
102294818c5SAlex Smith #endif
103294818c5SAlex Smith
104294818c5SAlex Smith #define PRINT_FPHEX_LONG_DOUBLE \
105294818c5SAlex Smith do { \
106294818c5SAlex Smith /* The "strange" 80 bit format on ix86 and m68k has an explicit \
107294818c5SAlex Smith leading digit in the 64 bit mantissa. */ \
108294818c5SAlex Smith unsigned long long int num; \
109294818c5SAlex Smith \
110294818c5SAlex Smith \
111294818c5SAlex Smith num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \
112294818c5SAlex Smith | fpnum.ldbl.ieee.mantissa1); \
113294818c5SAlex Smith \
114294818c5SAlex Smith zero_mantissa = num == 0; \
115294818c5SAlex Smith \
116294818c5SAlex Smith if (sizeof (unsigned long int) > 6) \
117294818c5SAlex Smith { \
118294818c5SAlex Smith numstr = _itoa_word (num, numbuf + sizeof numbuf, 16, \
119294818c5SAlex Smith info->spec == 'A'); \
120294818c5SAlex Smith wnumstr = _itowa_word (num, \
121294818c5SAlex Smith wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\
122294818c5SAlex Smith 16, info->spec == 'A'); \
123294818c5SAlex Smith } \
124294818c5SAlex Smith else \
125294818c5SAlex Smith { \
126294818c5SAlex Smith numstr = _itoa (num, numbuf + sizeof numbuf, 16, info->spec == 'A');\
127294818c5SAlex Smith wnumstr = _itowa (num, \
128294818c5SAlex Smith wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \
129294818c5SAlex Smith 16, info->spec == 'A'); \
130294818c5SAlex Smith } \
131294818c5SAlex Smith \
132294818c5SAlex Smith /* Fill with zeroes. */ \
133294818c5SAlex Smith while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \
134294818c5SAlex Smith { \
135294818c5SAlex Smith *--numstr = '0'; \
136294818c5SAlex Smith *--wnumstr = L'0'; \
137294818c5SAlex Smith } \
138294818c5SAlex Smith \
139294818c5SAlex Smith /* We use a full nibble for the leading digit. */ \
140294818c5SAlex Smith leading = *numstr++; \
141*6239b2a9SJérôme Duval wnumstr++; \
142294818c5SAlex Smith \
143294818c5SAlex Smith /* We have 3 bits from the mantissa in the leading nibble. \
144294818c5SAlex Smith Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \
145294818c5SAlex Smith exponent = fpnum.ldbl.ieee.exponent; \
146294818c5SAlex Smith \
147294818c5SAlex Smith if (exponent == 0) \
148294818c5SAlex Smith { \
149294818c5SAlex Smith if (zero_mantissa) \
150294818c5SAlex Smith expnegative = 0; \
151294818c5SAlex Smith else \
152294818c5SAlex Smith { \
153294818c5SAlex Smith /* This is a denormalized number. */ \
154294818c5SAlex Smith expnegative = 1; \
155294818c5SAlex Smith /* This is a hook for the m68k long double format, where the \
156294818c5SAlex Smith exponent bias is the same for normalized and denormalized \
157294818c5SAlex Smith numbers. */ \
158294818c5SAlex Smith exponent = LONG_DOUBLE_DENORM_BIAS + 3; \
159294818c5SAlex Smith } \
160294818c5SAlex Smith } \
161294818c5SAlex Smith else if (exponent >= IEEE854_LONG_DOUBLE_BIAS + 3) \
162294818c5SAlex Smith { \
163294818c5SAlex Smith expnegative = 0; \
164294818c5SAlex Smith exponent -= IEEE854_LONG_DOUBLE_BIAS + 3; \
165294818c5SAlex Smith } \
166294818c5SAlex Smith else \
167294818c5SAlex Smith { \
168294818c5SAlex Smith expnegative = 1; \
169294818c5SAlex Smith exponent = -(exponent - (IEEE854_LONG_DOUBLE_BIAS + 3)); \
170294818c5SAlex Smith } \
171294818c5SAlex Smith } while (0)
172294818c5SAlex Smith
1735ffbe7d7SAugustin Cavalier #endif /* __x86_64__ || __i386__ */
174294818c5SAlex Smith
175294818c5SAlex Smith
1765af32e75SAxel Dörfler int
__printf_fphex(FILE * fp,const struct printf_info * info,const void * const * args)1775af32e75SAxel Dörfler __printf_fphex (FILE *fp,
1785af32e75SAxel Dörfler const struct printf_info *info,
1795af32e75SAxel Dörfler const void *const *args)
1805af32e75SAxel Dörfler {
1815af32e75SAxel Dörfler /* The floating-point value to output. */
1825af32e75SAxel Dörfler union
1835af32e75SAxel Dörfler {
1845af32e75SAxel Dörfler union ieee754_double dbl;
1855af32e75SAxel Dörfler union ieee854_long_double ldbl;
1865af32e75SAxel Dörfler }
1875af32e75SAxel Dörfler fpnum;
1885af32e75SAxel Dörfler
1895af32e75SAxel Dörfler /* Locale-dependent representation of decimal point. */
1905af32e75SAxel Dörfler const char *decimal;
1915af32e75SAxel Dörfler wchar_t decimalwc;
1925af32e75SAxel Dörfler
1935af32e75SAxel Dörfler /* "NaN" or "Inf" for the special cases. */
1945af32e75SAxel Dörfler const char *special = NULL;
1955af32e75SAxel Dörfler const wchar_t *wspecial = NULL;
1965af32e75SAxel Dörfler
1975af32e75SAxel Dörfler /* Buffer for the generated number string for the mantissa. The
1985af32e75SAxel Dörfler maximal size for the mantissa is 128 bits. */
1995af32e75SAxel Dörfler char numbuf[32];
200d1716b27SOliver Tappe char *numstr="";
2015af32e75SAxel Dörfler char *numend;
2025af32e75SAxel Dörfler wchar_t wnumbuf[32];
203d1716b27SOliver Tappe wchar_t *wnumstr=L"";
2045af32e75SAxel Dörfler wchar_t *wnumend;
2055af32e75SAxel Dörfler int negative;
2065af32e75SAxel Dörfler
2075af32e75SAxel Dörfler /* The maximal exponent of two in decimal notation has 5 digits. */
2085af32e75SAxel Dörfler char expbuf[5];
2095af32e75SAxel Dörfler char *expstr;
2105af32e75SAxel Dörfler wchar_t wexpbuf[5];
2115af32e75SAxel Dörfler wchar_t *wexpstr;
212d1716b27SOliver Tappe int expnegative = 0;
213d1716b27SOliver Tappe int exponent = 0;
2145af32e75SAxel Dörfler
2155af32e75SAxel Dörfler /* Non-zero is mantissa is zero. */
216d1716b27SOliver Tappe int zero_mantissa = 1;
2175af32e75SAxel Dörfler
2185af32e75SAxel Dörfler /* The leading digit before the decimal point. */
219d1716b27SOliver Tappe char leading = '0';
2205af32e75SAxel Dörfler
2215af32e75SAxel Dörfler /* Precision. */
2225af32e75SAxel Dörfler int precision = info->prec;
2235af32e75SAxel Dörfler
2245af32e75SAxel Dörfler /* Width. */
2255af32e75SAxel Dörfler int width = info->width;
2265af32e75SAxel Dörfler
2275af32e75SAxel Dörfler /* Number of characters written. */
2285af32e75SAxel Dörfler int done = 0;
2295af32e75SAxel Dörfler
2305af32e75SAxel Dörfler /* Nonzero if this is output on a wide character stream. */
2315af32e75SAxel Dörfler int wide = info->wide;
2325af32e75SAxel Dörfler
2335af32e75SAxel Dörfler
2345af32e75SAxel Dörfler /* Figure out the decimal point character. */
2355af32e75SAxel Dörfler if (info->extra == 0)
2365af32e75SAxel Dörfler {
2375af32e75SAxel Dörfler decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
2385af32e75SAxel Dörfler decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
2395af32e75SAxel Dörfler }
2405af32e75SAxel Dörfler else
2415af32e75SAxel Dörfler {
2425af32e75SAxel Dörfler decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
2435af32e75SAxel Dörfler decimalwc = _NL_CURRENT_WORD (LC_MONETARY,
2445af32e75SAxel Dörfler _NL_MONETARY_DECIMAL_POINT_WC);
2455af32e75SAxel Dörfler }
2465af32e75SAxel Dörfler /* The decimal point character must never be zero. */
2475af32e75SAxel Dörfler assert (*decimal != '\0' && decimalwc != L'\0');
2485af32e75SAxel Dörfler
2495af32e75SAxel Dörfler
2505af32e75SAxel Dörfler /* Fetch the argument value. */
2515af32e75SAxel Dörfler #ifndef __NO_LONG_DOUBLE_MATH
2525af32e75SAxel Dörfler if (info->is_long_double && sizeof (long double) > sizeof (double))
2535af32e75SAxel Dörfler {
2545af32e75SAxel Dörfler fpnum.ldbl.d = *(const long double *) args[0];
2555af32e75SAxel Dörfler
2565af32e75SAxel Dörfler /* Check for special values: not a number or infinity. */
2577e8263e5SAugustin Cavalier if (isnan (fpnum.ldbl.d))
2585af32e75SAxel Dörfler {
2595af32e75SAxel Dörfler if (isupper (info->spec))
2605af32e75SAxel Dörfler {
2615af32e75SAxel Dörfler special = "NAN";
2625af32e75SAxel Dörfler wspecial = L"NAN";
2635af32e75SAxel Dörfler }
2645af32e75SAxel Dörfler else
2655af32e75SAxel Dörfler {
2665af32e75SAxel Dörfler special = "nan";
2675af32e75SAxel Dörfler wspecial = L"nan";
2685af32e75SAxel Dörfler }
2695af32e75SAxel Dörfler negative = 0;
2705af32e75SAxel Dörfler }
2715af32e75SAxel Dörfler else
2725af32e75SAxel Dörfler {
2737e8263e5SAugustin Cavalier if (isinf (fpnum.ldbl.d))
2745af32e75SAxel Dörfler {
2755af32e75SAxel Dörfler if (isupper (info->spec))
2765af32e75SAxel Dörfler {
2775af32e75SAxel Dörfler special = "INF";
2785af32e75SAxel Dörfler wspecial = L"INF";
2795af32e75SAxel Dörfler }
2805af32e75SAxel Dörfler else
2815af32e75SAxel Dörfler {
2825af32e75SAxel Dörfler special = "inf";
2835af32e75SAxel Dörfler wspecial = L"inf";
2845af32e75SAxel Dörfler }
2855af32e75SAxel Dörfler }
2865af32e75SAxel Dörfler
2875af32e75SAxel Dörfler negative = signbit (fpnum.ldbl.d);
2885af32e75SAxel Dörfler }
2895af32e75SAxel Dörfler }
2905af32e75SAxel Dörfler else
2915af32e75SAxel Dörfler #endif /* no long double */
2925af32e75SAxel Dörfler {
2935af32e75SAxel Dörfler fpnum.dbl.d = *(const double *) args[0];
2945af32e75SAxel Dörfler
2955af32e75SAxel Dörfler /* Check for special values: not a number or infinity. */
296614858a9SAlexander von Gluck IV if (isnan (fpnum.dbl.d))
2975af32e75SAxel Dörfler {
2985af32e75SAxel Dörfler if (isupper (info->spec))
2995af32e75SAxel Dörfler {
3005af32e75SAxel Dörfler special = "NAN";
3015af32e75SAxel Dörfler wspecial = L"NAN";
3025af32e75SAxel Dörfler }
3035af32e75SAxel Dörfler else
3045af32e75SAxel Dörfler {
3055af32e75SAxel Dörfler special = "nan";
3065af32e75SAxel Dörfler wspecial = L"nan";
3075af32e75SAxel Dörfler }
3085af32e75SAxel Dörfler negative = 0;
3095af32e75SAxel Dörfler }
3105af32e75SAxel Dörfler else
3115af32e75SAxel Dörfler {
312614858a9SAlexander von Gluck IV if (isinf (fpnum.dbl.d))
3135af32e75SAxel Dörfler {
3145af32e75SAxel Dörfler if (isupper (info->spec))
3155af32e75SAxel Dörfler {
3165af32e75SAxel Dörfler special = "INF";
3175af32e75SAxel Dörfler wspecial = L"INF";
3185af32e75SAxel Dörfler }
3195af32e75SAxel Dörfler else
3205af32e75SAxel Dörfler {
3215af32e75SAxel Dörfler special = "inf";
3225af32e75SAxel Dörfler wspecial = L"inf";
3235af32e75SAxel Dörfler }
3245af32e75SAxel Dörfler }
3255af32e75SAxel Dörfler
3265af32e75SAxel Dörfler negative = signbit (fpnum.dbl.d);
3275af32e75SAxel Dörfler }
3285af32e75SAxel Dörfler }
3295af32e75SAxel Dörfler
3305af32e75SAxel Dörfler if (special)
3315af32e75SAxel Dörfler {
3325af32e75SAxel Dörfler int width = info->width;
3335af32e75SAxel Dörfler
3345af32e75SAxel Dörfler if (negative || info->showsign || info->space)
3355af32e75SAxel Dörfler --width;
3365af32e75SAxel Dörfler width -= 3;
3375af32e75SAxel Dörfler
3385af32e75SAxel Dörfler if (!info->left && width > 0)
3395af32e75SAxel Dörfler PADN (' ', width);
3405af32e75SAxel Dörfler
3415af32e75SAxel Dörfler if (negative)
3425af32e75SAxel Dörfler outchar ('-');
3435af32e75SAxel Dörfler else if (info->showsign)
3445af32e75SAxel Dörfler outchar ('+');
3455af32e75SAxel Dörfler else if (info->space)
3465af32e75SAxel Dörfler outchar (' ');
3475af32e75SAxel Dörfler
3485af32e75SAxel Dörfler PRINT (special, wspecial, 3);
3495af32e75SAxel Dörfler
3505af32e75SAxel Dörfler if (info->left && width > 0)
3515af32e75SAxel Dörfler PADN (' ', width);
3525af32e75SAxel Dörfler
3535af32e75SAxel Dörfler return done;
3545af32e75SAxel Dörfler }
3555af32e75SAxel Dörfler
3565af32e75SAxel Dörfler if (info->is_long_double == 0 || sizeof (double) == sizeof (long double))
3575af32e75SAxel Dörfler {
3585af32e75SAxel Dörfler /* We have 52 bits of mantissa plus one implicit digit. Since
3595af32e75SAxel Dörfler 52 bits are representable without rest using hexadecimal
3605af32e75SAxel Dörfler digits we use only the implicit digits for the number before
3615af32e75SAxel Dörfler the decimal point. */
3625af32e75SAxel Dörfler unsigned long long int num;
3635af32e75SAxel Dörfler
3645af32e75SAxel Dörfler num = (((unsigned long long int) fpnum.dbl.ieee.mantissa0) << 32
3655af32e75SAxel Dörfler | fpnum.dbl.ieee.mantissa1);
3665af32e75SAxel Dörfler
3675af32e75SAxel Dörfler zero_mantissa = num == 0;
3685af32e75SAxel Dörfler
3695af32e75SAxel Dörfler if (sizeof (unsigned long int) > 6)
3705af32e75SAxel Dörfler {
3715af32e75SAxel Dörfler wnumstr = _itowa_word (num, wnumbuf + (sizeof wnumbuf) / sizeof (wchar_t), 16,
3725af32e75SAxel Dörfler info->spec == 'A');
3735af32e75SAxel Dörfler numstr = _itoa_word (num, numbuf + sizeof numbuf, 16,
3745af32e75SAxel Dörfler info->spec == 'A');
3755af32e75SAxel Dörfler }
3765af32e75SAxel Dörfler else
3775af32e75SAxel Dörfler {
3785af32e75SAxel Dörfler wnumstr = _itowa (num, wnumbuf + sizeof wnumbuf / sizeof (wchar_t), 16,
3795af32e75SAxel Dörfler info->spec == 'A');
3805af32e75SAxel Dörfler numstr = _itoa (num, numbuf + sizeof numbuf, 16,
3815af32e75SAxel Dörfler info->spec == 'A');
3825af32e75SAxel Dörfler }
3835af32e75SAxel Dörfler
3845af32e75SAxel Dörfler /* Fill with zeroes. */
3855af32e75SAxel Dörfler while (wnumstr > wnumbuf + (sizeof wnumbuf - 52) / sizeof (wchar_t))
3865af32e75SAxel Dörfler {
3875af32e75SAxel Dörfler *--wnumstr = L'0';
3885af32e75SAxel Dörfler *--numstr = '0';
3895af32e75SAxel Dörfler }
3905af32e75SAxel Dörfler
3915af32e75SAxel Dörfler leading = fpnum.dbl.ieee.exponent == 0 ? '0' : '1';
3925af32e75SAxel Dörfler
3935af32e75SAxel Dörfler exponent = fpnum.dbl.ieee.exponent;
3945af32e75SAxel Dörfler
3955af32e75SAxel Dörfler if (exponent == 0)
3965af32e75SAxel Dörfler {
3975af32e75SAxel Dörfler if (zero_mantissa)
3985af32e75SAxel Dörfler expnegative = 0;
3995af32e75SAxel Dörfler else
4005af32e75SAxel Dörfler {
4015af32e75SAxel Dörfler /* This is a denormalized number. */
4025af32e75SAxel Dörfler expnegative = 1;
4035af32e75SAxel Dörfler exponent = IEEE754_DOUBLE_BIAS - 1;
4045af32e75SAxel Dörfler }
4055af32e75SAxel Dörfler }
4065af32e75SAxel Dörfler else if (exponent >= IEEE754_DOUBLE_BIAS)
4075af32e75SAxel Dörfler {
4085af32e75SAxel Dörfler expnegative = 0;
4095af32e75SAxel Dörfler exponent -= IEEE754_DOUBLE_BIAS;
4105af32e75SAxel Dörfler }
4115af32e75SAxel Dörfler else
4125af32e75SAxel Dörfler {
4135af32e75SAxel Dörfler expnegative = 1;
4145af32e75SAxel Dörfler exponent = -(exponent - IEEE754_DOUBLE_BIAS);
4155af32e75SAxel Dörfler }
4165af32e75SAxel Dörfler }
4175af32e75SAxel Dörfler #ifdef PRINT_FPHEX_LONG_DOUBLE
4185af32e75SAxel Dörfler else
4195af32e75SAxel Dörfler PRINT_FPHEX_LONG_DOUBLE;
4205af32e75SAxel Dörfler #endif
4215af32e75SAxel Dörfler
4225af32e75SAxel Dörfler /* Look for trailing zeroes. */
4235af32e75SAxel Dörfler if (! zero_mantissa)
4245af32e75SAxel Dörfler {
425294818c5SAlex Smith wnumend = &wnumbuf[sizeof wnumbuf / sizeof wnumbuf[0]];
426294818c5SAlex Smith numend = &numbuf[sizeof numbuf / sizeof numbuf[0]];
4275af32e75SAxel Dörfler while (wnumend[-1] == L'0')
4285af32e75SAxel Dörfler {
4295af32e75SAxel Dörfler --wnumend;
4305af32e75SAxel Dörfler --numend;
4315af32e75SAxel Dörfler }
4325af32e75SAxel Dörfler
4335af32e75SAxel Dörfler if (precision == -1)
4345af32e75SAxel Dörfler precision = numend - numstr;
4355af32e75SAxel Dörfler else if (precision < numend - numstr
4365af32e75SAxel Dörfler && (numstr[precision] > '8'
4375af32e75SAxel Dörfler || (('A' < '0' || 'a' < '0')
4385af32e75SAxel Dörfler && numstr[precision] < '0')
4395af32e75SAxel Dörfler || (numstr[precision] == '8'
4405af32e75SAxel Dörfler && (precision + 1 < numend - numstr
4415af32e75SAxel Dörfler /* Round to even. */
4425af32e75SAxel Dörfler || (precision > 0
4435af32e75SAxel Dörfler && ((numstr[precision - 1] & 1)
4445af32e75SAxel Dörfler ^ (isdigit (numstr[precision - 1]) == 0)))
4455af32e75SAxel Dörfler || (precision == 0
4465af32e75SAxel Dörfler && ((leading & 1)
4475af32e75SAxel Dörfler ^ (isdigit (leading) == 0)))))))
4485af32e75SAxel Dörfler {
4495af32e75SAxel Dörfler /* Round up. */
4505af32e75SAxel Dörfler int cnt = precision;
4515af32e75SAxel Dörfler while (--cnt >= 0)
4525af32e75SAxel Dörfler {
4535af32e75SAxel Dörfler char ch = numstr[cnt];
4545af32e75SAxel Dörfler /* We assume that the digits and the letters are ordered
4555af32e75SAxel Dörfler like in ASCII. This is true for the rest of GNU, too. */
4565af32e75SAxel Dörfler if (ch == '9')
4575af32e75SAxel Dörfler {
4585af32e75SAxel Dörfler wnumstr[cnt] = (wchar_t) info->spec;
4595af32e75SAxel Dörfler numstr[cnt] = info->spec; /* This is tricky,
4605af32e75SAxel Dörfler think about it! */
4615af32e75SAxel Dörfler break;
4625af32e75SAxel Dörfler }
4635af32e75SAxel Dörfler else if (tolower (ch) < 'f')
4645af32e75SAxel Dörfler {
4655af32e75SAxel Dörfler ++numstr[cnt];
4665af32e75SAxel Dörfler ++wnumstr[cnt];
4675af32e75SAxel Dörfler break;
4685af32e75SAxel Dörfler }
4695af32e75SAxel Dörfler else
4705af32e75SAxel Dörfler {
4715af32e75SAxel Dörfler numstr[cnt] = '0';
4725af32e75SAxel Dörfler wnumstr[cnt] = L'0';
4735af32e75SAxel Dörfler }
4745af32e75SAxel Dörfler }
4755af32e75SAxel Dörfler if (cnt < 0)
4765af32e75SAxel Dörfler {
4775af32e75SAxel Dörfler /* The mantissa so far was fff...f Now increment the
4785af32e75SAxel Dörfler leading digit. Here it is again possible that we
4795af32e75SAxel Dörfler get an overflow. */
4805af32e75SAxel Dörfler if (leading == '9')
4815af32e75SAxel Dörfler leading = info->spec;
4825af32e75SAxel Dörfler else if (tolower (leading) < 'f')
4835af32e75SAxel Dörfler ++leading;
4845af32e75SAxel Dörfler else
4855af32e75SAxel Dörfler {
486294818c5SAlex Smith leading = '1';
4875af32e75SAxel Dörfler if (expnegative)
4885af32e75SAxel Dörfler {
489294818c5SAlex Smith exponent -= 4;
490294818c5SAlex Smith if (exponent <= 0)
491294818c5SAlex Smith {
492294818c5SAlex Smith exponent = -exponent;
4935af32e75SAxel Dörfler expnegative = 0;
4945af32e75SAxel Dörfler }
495294818c5SAlex Smith }
4965af32e75SAxel Dörfler else
4975af32e75SAxel Dörfler exponent += 4;
4985af32e75SAxel Dörfler }
4995af32e75SAxel Dörfler }
5005af32e75SAxel Dörfler }
5015af32e75SAxel Dörfler }
5025af32e75SAxel Dörfler else
5035af32e75SAxel Dörfler {
5045af32e75SAxel Dörfler if (precision == -1)
5055af32e75SAxel Dörfler precision = 0;
5065af32e75SAxel Dörfler numend = numstr;
5075af32e75SAxel Dörfler wnumend = wnumstr;
5085af32e75SAxel Dörfler }
5095af32e75SAxel Dörfler
5105af32e75SAxel Dörfler /* Now we can compute the exponent string. */
5115af32e75SAxel Dörfler expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0);
5125af32e75SAxel Dörfler wexpstr = _itowa_word (exponent,
5135af32e75SAxel Dörfler wexpbuf + sizeof wexpbuf / sizeof (wchar_t), 10, 0);
5145af32e75SAxel Dörfler
5155af32e75SAxel Dörfler /* Now we have all information to compute the size. */
5165af32e75SAxel Dörfler width -= ((negative || info->showsign || info->space)
5175af32e75SAxel Dörfler /* Sign. */
5185af32e75SAxel Dörfler + 2 + 1 + 0 + precision + 1 + 1
5195af32e75SAxel Dörfler /* 0x h . hhh P ExpoSign. */
5205af32e75SAxel Dörfler + ((expbuf + sizeof expbuf) - expstr));
5215af32e75SAxel Dörfler /* Exponent. */
5225af32e75SAxel Dörfler
523294818c5SAlex Smith /* Count the decimal point.
524294818c5SAlex Smith A special case when the mantissa or the precision is zero and the `#'
525294818c5SAlex Smith is not given. In this case we must not print the decimal point. */
5265af32e75SAxel Dörfler if (precision > 0 || info->alt)
5275af32e75SAxel Dörfler width -= wide ? 1 : strlen (decimal);
5285af32e75SAxel Dörfler
529294818c5SAlex Smith if (!info->left && info->pad != '0' && width > 0)
5305af32e75SAxel Dörfler PADN (' ', width);
5315af32e75SAxel Dörfler
5325af32e75SAxel Dörfler if (negative)
5335af32e75SAxel Dörfler outchar ('-');
5345af32e75SAxel Dörfler else if (info->showsign)
5355af32e75SAxel Dörfler outchar ('+');
5365af32e75SAxel Dörfler else if (info->space)
5375af32e75SAxel Dörfler outchar (' ');
5385af32e75SAxel Dörfler
5395af32e75SAxel Dörfler outchar ('0');
5405af32e75SAxel Dörfler if ('X' - 'A' == 'x' - 'a')
5415af32e75SAxel Dörfler outchar (info->spec + ('x' - 'a'));
5425af32e75SAxel Dörfler else
5435af32e75SAxel Dörfler outchar (info->spec == 'A' ? 'X' : 'x');
544294818c5SAlex Smith
545294818c5SAlex Smith if (!info->left && info->pad == '0' && width > 0)
546294818c5SAlex Smith PADN ('0', width);
547294818c5SAlex Smith
5485af32e75SAxel Dörfler outchar (leading);
5495af32e75SAxel Dörfler
5505af32e75SAxel Dörfler if (precision > 0 || info->alt)
5515af32e75SAxel Dörfler {
5525af32e75SAxel Dörfler const wchar_t *wtmp = &decimalwc;
5535af32e75SAxel Dörfler PRINT (decimal, wtmp, wide ? 1 : strlen (decimal));
5545af32e75SAxel Dörfler }
5555af32e75SAxel Dörfler
5565af32e75SAxel Dörfler if (precision > 0)
5575af32e75SAxel Dörfler {
5585af32e75SAxel Dörfler ssize_t tofill = precision - (numend - numstr);
5595af32e75SAxel Dörfler PRINT (numstr, wnumstr, MIN (numend - numstr, precision));
5605af32e75SAxel Dörfler if (tofill > 0)
5615af32e75SAxel Dörfler PADN ('0', tofill);
5625af32e75SAxel Dörfler }
5635af32e75SAxel Dörfler
5645af32e75SAxel Dörfler if ('P' - 'A' == 'p' - 'a')
5655af32e75SAxel Dörfler outchar (info->spec + ('p' - 'a'));
5665af32e75SAxel Dörfler else
5675af32e75SAxel Dörfler outchar (info->spec == 'A' ? 'P' : 'p');
5685af32e75SAxel Dörfler
5695af32e75SAxel Dörfler outchar (expnegative ? '-' : '+');
5705af32e75SAxel Dörfler
5715af32e75SAxel Dörfler PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr);
5725af32e75SAxel Dörfler
5735af32e75SAxel Dörfler if (info->left && info->pad != '0' && width > 0)
5745af32e75SAxel Dörfler PADN (info->pad, width);
5755af32e75SAxel Dörfler
5765af32e75SAxel Dörfler return done;
5775af32e75SAxel Dörfler }
578