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 36*d1716b27SOliver Tappe int __printf_fphex (FILE *fp, const struct printf_info *info, 37*d1716b27SOliver Tappe const void *const *args); 38*d1716b27SOliver 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 */ 575af32e75SAxel Dörfler 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 935af32e75SAxel Dörfler 945af32e75SAxel Dörfler 95294818c5SAlex Smith 96*d1716b27SOliver Tappe #if defined(__x86_64__) || defined(__INTEL__) 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++; \ 141294818c5SAlex Smith \ 142294818c5SAlex Smith /* We have 3 bits from the mantissa in the leading nibble. \ 143294818c5SAlex Smith Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \ 144294818c5SAlex Smith exponent = fpnum.ldbl.ieee.exponent; \ 145294818c5SAlex Smith \ 146294818c5SAlex Smith if (exponent == 0) \ 147294818c5SAlex Smith { \ 148294818c5SAlex Smith if (zero_mantissa) \ 149294818c5SAlex Smith expnegative = 0; \ 150294818c5SAlex Smith else \ 151294818c5SAlex Smith { \ 152294818c5SAlex Smith /* This is a denormalized number. */ \ 153294818c5SAlex Smith expnegative = 1; \ 154294818c5SAlex Smith /* This is a hook for the m68k long double format, where the \ 155294818c5SAlex Smith exponent bias is the same for normalized and denormalized \ 156294818c5SAlex Smith numbers. */ \ 157294818c5SAlex Smith exponent = LONG_DOUBLE_DENORM_BIAS + 3; \ 158294818c5SAlex Smith } \ 159294818c5SAlex Smith } \ 160294818c5SAlex Smith else if (exponent >= IEEE854_LONG_DOUBLE_BIAS + 3) \ 161294818c5SAlex Smith { \ 162294818c5SAlex Smith expnegative = 0; \ 163294818c5SAlex Smith exponent -= IEEE854_LONG_DOUBLE_BIAS + 3; \ 164294818c5SAlex Smith } \ 165294818c5SAlex Smith else \ 166294818c5SAlex Smith { \ 167294818c5SAlex Smith expnegative = 1; \ 168294818c5SAlex Smith exponent = -(exponent - (IEEE854_LONG_DOUBLE_BIAS + 3)); \ 169294818c5SAlex Smith } \ 170294818c5SAlex Smith } while (0) 171294818c5SAlex Smith 172*d1716b27SOliver Tappe #endif /* __x86_64__ || __INTEL__ */ 173294818c5SAlex Smith 174294818c5SAlex Smith 1755af32e75SAxel Dörfler int 1765af32e75SAxel Dörfler __printf_fphex (FILE *fp, 1775af32e75SAxel Dörfler const struct printf_info *info, 1785af32e75SAxel Dörfler const void *const *args) 1795af32e75SAxel Dörfler { 1805af32e75SAxel Dörfler /* The floating-point value to output. */ 1815af32e75SAxel Dörfler union 1825af32e75SAxel Dörfler { 1835af32e75SAxel Dörfler union ieee754_double dbl; 1845af32e75SAxel Dörfler union ieee854_long_double ldbl; 1855af32e75SAxel Dörfler } 1865af32e75SAxel Dörfler fpnum; 1875af32e75SAxel Dörfler 1885af32e75SAxel Dörfler /* Locale-dependent representation of decimal point. */ 1895af32e75SAxel Dörfler const char *decimal; 1905af32e75SAxel Dörfler wchar_t decimalwc; 1915af32e75SAxel Dörfler 1925af32e75SAxel Dörfler /* "NaN" or "Inf" for the special cases. */ 1935af32e75SAxel Dörfler const char *special = NULL; 1945af32e75SAxel Dörfler const wchar_t *wspecial = NULL; 1955af32e75SAxel Dörfler 1965af32e75SAxel Dörfler /* Buffer for the generated number string for the mantissa. The 1975af32e75SAxel Dörfler maximal size for the mantissa is 128 bits. */ 1985af32e75SAxel Dörfler char numbuf[32]; 199*d1716b27SOliver Tappe char *numstr=""; 2005af32e75SAxel Dörfler char *numend; 2015af32e75SAxel Dörfler wchar_t wnumbuf[32]; 202*d1716b27SOliver Tappe wchar_t *wnumstr=L""; 2035af32e75SAxel Dörfler wchar_t *wnumend; 2045af32e75SAxel Dörfler int negative; 2055af32e75SAxel Dörfler 2065af32e75SAxel Dörfler /* The maximal exponent of two in decimal notation has 5 digits. */ 2075af32e75SAxel Dörfler char expbuf[5]; 2085af32e75SAxel Dörfler char *expstr; 2095af32e75SAxel Dörfler wchar_t wexpbuf[5]; 2105af32e75SAxel Dörfler wchar_t *wexpstr; 211*d1716b27SOliver Tappe int expnegative = 0; 212*d1716b27SOliver Tappe int exponent = 0; 2135af32e75SAxel Dörfler 2145af32e75SAxel Dörfler /* Non-zero is mantissa is zero. */ 215*d1716b27SOliver Tappe int zero_mantissa = 1; 2165af32e75SAxel Dörfler 2175af32e75SAxel Dörfler /* The leading digit before the decimal point. */ 218*d1716b27SOliver Tappe char leading = '0'; 2195af32e75SAxel Dörfler 2205af32e75SAxel Dörfler /* Precision. */ 2215af32e75SAxel Dörfler int precision = info->prec; 2225af32e75SAxel Dörfler 2235af32e75SAxel Dörfler /* Width. */ 2245af32e75SAxel Dörfler int width = info->width; 2255af32e75SAxel Dörfler 2265af32e75SAxel Dörfler /* Number of characters written. */ 2275af32e75SAxel Dörfler int done = 0; 2285af32e75SAxel Dörfler 2295af32e75SAxel Dörfler /* Nonzero if this is output on a wide character stream. */ 2305af32e75SAxel Dörfler int wide = info->wide; 2315af32e75SAxel Dörfler 2325af32e75SAxel Dörfler 2335af32e75SAxel Dörfler /* Figure out the decimal point character. */ 2345af32e75SAxel Dörfler if (info->extra == 0) 2355af32e75SAxel Dörfler { 2365af32e75SAxel Dörfler decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); 2375af32e75SAxel Dörfler decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC); 2385af32e75SAxel Dörfler } 2395af32e75SAxel Dörfler else 2405af32e75SAxel Dörfler { 2415af32e75SAxel Dörfler decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT); 2425af32e75SAxel Dörfler decimalwc = _NL_CURRENT_WORD (LC_MONETARY, 2435af32e75SAxel Dörfler _NL_MONETARY_DECIMAL_POINT_WC); 2445af32e75SAxel Dörfler } 2455af32e75SAxel Dörfler /* The decimal point character must never be zero. */ 2465af32e75SAxel Dörfler assert (*decimal != '\0' && decimalwc != L'\0'); 2475af32e75SAxel Dörfler 2485af32e75SAxel Dörfler 2495af32e75SAxel Dörfler /* Fetch the argument value. */ 2505af32e75SAxel Dörfler #ifndef __NO_LONG_DOUBLE_MATH 2515af32e75SAxel Dörfler if (info->is_long_double && sizeof (long double) > sizeof (double)) 2525af32e75SAxel Dörfler { 2535af32e75SAxel Dörfler fpnum.ldbl.d = *(const long double *) args[0]; 2545af32e75SAxel Dörfler 2555af32e75SAxel Dörfler /* Check for special values: not a number or infinity. */ 2565af32e75SAxel Dörfler if (__isnanl (fpnum.ldbl.d)) 2575af32e75SAxel Dörfler { 2585af32e75SAxel Dörfler if (isupper (info->spec)) 2595af32e75SAxel Dörfler { 2605af32e75SAxel Dörfler special = "NAN"; 2615af32e75SAxel Dörfler wspecial = L"NAN"; 2625af32e75SAxel Dörfler } 2635af32e75SAxel Dörfler else 2645af32e75SAxel Dörfler { 2655af32e75SAxel Dörfler special = "nan"; 2665af32e75SAxel Dörfler wspecial = L"nan"; 2675af32e75SAxel Dörfler } 2685af32e75SAxel Dörfler negative = 0; 2695af32e75SAxel Dörfler } 2705af32e75SAxel Dörfler else 2715af32e75SAxel Dörfler { 2725af32e75SAxel Dörfler if (__isinfl (fpnum.ldbl.d)) 2735af32e75SAxel Dörfler { 2745af32e75SAxel Dörfler if (isupper (info->spec)) 2755af32e75SAxel Dörfler { 2765af32e75SAxel Dörfler special = "INF"; 2775af32e75SAxel Dörfler wspecial = L"INF"; 2785af32e75SAxel Dörfler } 2795af32e75SAxel Dörfler else 2805af32e75SAxel Dörfler { 2815af32e75SAxel Dörfler special = "inf"; 2825af32e75SAxel Dörfler wspecial = L"inf"; 2835af32e75SAxel Dörfler } 2845af32e75SAxel Dörfler } 2855af32e75SAxel Dörfler 2865af32e75SAxel Dörfler negative = signbit (fpnum.ldbl.d); 2875af32e75SAxel Dörfler } 2885af32e75SAxel Dörfler } 2895af32e75SAxel Dörfler else 2905af32e75SAxel Dörfler #endif /* no long double */ 2915af32e75SAxel Dörfler { 2925af32e75SAxel Dörfler fpnum.dbl.d = *(const double *) args[0]; 2935af32e75SAxel Dörfler 2945af32e75SAxel Dörfler /* Check for special values: not a number or infinity. */ 2955af32e75SAxel Dörfler if (__isnan (fpnum.dbl.d)) 2965af32e75SAxel Dörfler { 2975af32e75SAxel Dörfler if (isupper (info->spec)) 2985af32e75SAxel Dörfler { 2995af32e75SAxel Dörfler special = "NAN"; 3005af32e75SAxel Dörfler wspecial = L"NAN"; 3015af32e75SAxel Dörfler } 3025af32e75SAxel Dörfler else 3035af32e75SAxel Dörfler { 3045af32e75SAxel Dörfler special = "nan"; 3055af32e75SAxel Dörfler wspecial = L"nan"; 3065af32e75SAxel Dörfler } 3075af32e75SAxel Dörfler negative = 0; 3085af32e75SAxel Dörfler } 3095af32e75SAxel Dörfler else 3105af32e75SAxel Dörfler { 3115af32e75SAxel Dörfler if (__isinf (fpnum.dbl.d)) 3125af32e75SAxel Dörfler { 3135af32e75SAxel Dörfler if (isupper (info->spec)) 3145af32e75SAxel Dörfler { 3155af32e75SAxel Dörfler special = "INF"; 3165af32e75SAxel Dörfler wspecial = L"INF"; 3175af32e75SAxel Dörfler } 3185af32e75SAxel Dörfler else 3195af32e75SAxel Dörfler { 3205af32e75SAxel Dörfler special = "inf"; 3215af32e75SAxel Dörfler wspecial = L"inf"; 3225af32e75SAxel Dörfler } 3235af32e75SAxel Dörfler } 3245af32e75SAxel Dörfler 3255af32e75SAxel Dörfler negative = signbit (fpnum.dbl.d); 3265af32e75SAxel Dörfler } 3275af32e75SAxel Dörfler } 3285af32e75SAxel Dörfler 3295af32e75SAxel Dörfler if (special) 3305af32e75SAxel Dörfler { 3315af32e75SAxel Dörfler int width = info->width; 3325af32e75SAxel Dörfler 3335af32e75SAxel Dörfler if (negative || info->showsign || info->space) 3345af32e75SAxel Dörfler --width; 3355af32e75SAxel Dörfler width -= 3; 3365af32e75SAxel Dörfler 3375af32e75SAxel Dörfler if (!info->left && width > 0) 3385af32e75SAxel Dörfler PADN (' ', width); 3395af32e75SAxel Dörfler 3405af32e75SAxel Dörfler if (negative) 3415af32e75SAxel Dörfler outchar ('-'); 3425af32e75SAxel Dörfler else if (info->showsign) 3435af32e75SAxel Dörfler outchar ('+'); 3445af32e75SAxel Dörfler else if (info->space) 3455af32e75SAxel Dörfler outchar (' '); 3465af32e75SAxel Dörfler 3475af32e75SAxel Dörfler PRINT (special, wspecial, 3); 3485af32e75SAxel Dörfler 3495af32e75SAxel Dörfler if (info->left && width > 0) 3505af32e75SAxel Dörfler PADN (' ', width); 3515af32e75SAxel Dörfler 3525af32e75SAxel Dörfler return done; 3535af32e75SAxel Dörfler } 3545af32e75SAxel Dörfler 3555af32e75SAxel Dörfler if (info->is_long_double == 0 || sizeof (double) == sizeof (long double)) 3565af32e75SAxel Dörfler { 3575af32e75SAxel Dörfler /* We have 52 bits of mantissa plus one implicit digit. Since 3585af32e75SAxel Dörfler 52 bits are representable without rest using hexadecimal 3595af32e75SAxel Dörfler digits we use only the implicit digits for the number before 3605af32e75SAxel Dörfler the decimal point. */ 3615af32e75SAxel Dörfler unsigned long long int num; 3625af32e75SAxel Dörfler 3635af32e75SAxel Dörfler num = (((unsigned long long int) fpnum.dbl.ieee.mantissa0) << 32 3645af32e75SAxel Dörfler | fpnum.dbl.ieee.mantissa1); 3655af32e75SAxel Dörfler 3665af32e75SAxel Dörfler zero_mantissa = num == 0; 3675af32e75SAxel Dörfler 3685af32e75SAxel Dörfler if (sizeof (unsigned long int) > 6) 3695af32e75SAxel Dörfler { 3705af32e75SAxel Dörfler wnumstr = _itowa_word (num, wnumbuf + (sizeof wnumbuf) / sizeof (wchar_t), 16, 3715af32e75SAxel Dörfler info->spec == 'A'); 3725af32e75SAxel Dörfler numstr = _itoa_word (num, numbuf + sizeof numbuf, 16, 3735af32e75SAxel Dörfler info->spec == 'A'); 3745af32e75SAxel Dörfler } 3755af32e75SAxel Dörfler else 3765af32e75SAxel Dörfler { 3775af32e75SAxel Dörfler wnumstr = _itowa (num, wnumbuf + sizeof wnumbuf / sizeof (wchar_t), 16, 3785af32e75SAxel Dörfler info->spec == 'A'); 3795af32e75SAxel Dörfler numstr = _itoa (num, numbuf + sizeof numbuf, 16, 3805af32e75SAxel Dörfler info->spec == 'A'); 3815af32e75SAxel Dörfler } 3825af32e75SAxel Dörfler 3835af32e75SAxel Dörfler /* Fill with zeroes. */ 3845af32e75SAxel Dörfler while (wnumstr > wnumbuf + (sizeof wnumbuf - 52) / sizeof (wchar_t)) 3855af32e75SAxel Dörfler { 3865af32e75SAxel Dörfler *--wnumstr = L'0'; 3875af32e75SAxel Dörfler *--numstr = '0'; 3885af32e75SAxel Dörfler } 3895af32e75SAxel Dörfler 3905af32e75SAxel Dörfler leading = fpnum.dbl.ieee.exponent == 0 ? '0' : '1'; 3915af32e75SAxel Dörfler 3925af32e75SAxel Dörfler exponent = fpnum.dbl.ieee.exponent; 3935af32e75SAxel Dörfler 3945af32e75SAxel Dörfler if (exponent == 0) 3955af32e75SAxel Dörfler { 3965af32e75SAxel Dörfler if (zero_mantissa) 3975af32e75SAxel Dörfler expnegative = 0; 3985af32e75SAxel Dörfler else 3995af32e75SAxel Dörfler { 4005af32e75SAxel Dörfler /* This is a denormalized number. */ 4015af32e75SAxel Dörfler expnegative = 1; 4025af32e75SAxel Dörfler exponent = IEEE754_DOUBLE_BIAS - 1; 4035af32e75SAxel Dörfler } 4045af32e75SAxel Dörfler } 4055af32e75SAxel Dörfler else if (exponent >= IEEE754_DOUBLE_BIAS) 4065af32e75SAxel Dörfler { 4075af32e75SAxel Dörfler expnegative = 0; 4085af32e75SAxel Dörfler exponent -= IEEE754_DOUBLE_BIAS; 4095af32e75SAxel Dörfler } 4105af32e75SAxel Dörfler else 4115af32e75SAxel Dörfler { 4125af32e75SAxel Dörfler expnegative = 1; 4135af32e75SAxel Dörfler exponent = -(exponent - IEEE754_DOUBLE_BIAS); 4145af32e75SAxel Dörfler } 4155af32e75SAxel Dörfler } 4165af32e75SAxel Dörfler #ifdef PRINT_FPHEX_LONG_DOUBLE 4175af32e75SAxel Dörfler else 4185af32e75SAxel Dörfler PRINT_FPHEX_LONG_DOUBLE; 4195af32e75SAxel Dörfler #endif 4205af32e75SAxel Dörfler 4215af32e75SAxel Dörfler /* Look for trailing zeroes. */ 4225af32e75SAxel Dörfler if (! zero_mantissa) 4235af32e75SAxel Dörfler { 424294818c5SAlex Smith wnumend = &wnumbuf[sizeof wnumbuf / sizeof wnumbuf[0]]; 425294818c5SAlex Smith numend = &numbuf[sizeof numbuf / sizeof numbuf[0]]; 4265af32e75SAxel Dörfler while (wnumend[-1] == L'0') 4275af32e75SAxel Dörfler { 4285af32e75SAxel Dörfler --wnumend; 4295af32e75SAxel Dörfler --numend; 4305af32e75SAxel Dörfler } 4315af32e75SAxel Dörfler 4325af32e75SAxel Dörfler if (precision == -1) 4335af32e75SAxel Dörfler precision = numend - numstr; 4345af32e75SAxel Dörfler else if (precision < numend - numstr 4355af32e75SAxel Dörfler && (numstr[precision] > '8' 4365af32e75SAxel Dörfler || (('A' < '0' || 'a' < '0') 4375af32e75SAxel Dörfler && numstr[precision] < '0') 4385af32e75SAxel Dörfler || (numstr[precision] == '8' 4395af32e75SAxel Dörfler && (precision + 1 < numend - numstr 4405af32e75SAxel Dörfler /* Round to even. */ 4415af32e75SAxel Dörfler || (precision > 0 4425af32e75SAxel Dörfler && ((numstr[precision - 1] & 1) 4435af32e75SAxel Dörfler ^ (isdigit (numstr[precision - 1]) == 0))) 4445af32e75SAxel Dörfler || (precision == 0 4455af32e75SAxel Dörfler && ((leading & 1) 4465af32e75SAxel Dörfler ^ (isdigit (leading) == 0))))))) 4475af32e75SAxel Dörfler { 4485af32e75SAxel Dörfler /* Round up. */ 4495af32e75SAxel Dörfler int cnt = precision; 4505af32e75SAxel Dörfler while (--cnt >= 0) 4515af32e75SAxel Dörfler { 4525af32e75SAxel Dörfler char ch = numstr[cnt]; 4535af32e75SAxel Dörfler /* We assume that the digits and the letters are ordered 4545af32e75SAxel Dörfler like in ASCII. This is true for the rest of GNU, too. */ 4555af32e75SAxel Dörfler if (ch == '9') 4565af32e75SAxel Dörfler { 4575af32e75SAxel Dörfler wnumstr[cnt] = (wchar_t) info->spec; 4585af32e75SAxel Dörfler numstr[cnt] = info->spec; /* This is tricky, 4595af32e75SAxel Dörfler think about it! */ 4605af32e75SAxel Dörfler break; 4615af32e75SAxel Dörfler } 4625af32e75SAxel Dörfler else if (tolower (ch) < 'f') 4635af32e75SAxel Dörfler { 4645af32e75SAxel Dörfler ++numstr[cnt]; 4655af32e75SAxel Dörfler ++wnumstr[cnt]; 4665af32e75SAxel Dörfler break; 4675af32e75SAxel Dörfler } 4685af32e75SAxel Dörfler else 4695af32e75SAxel Dörfler { 4705af32e75SAxel Dörfler numstr[cnt] = '0'; 4715af32e75SAxel Dörfler wnumstr[cnt] = L'0'; 4725af32e75SAxel Dörfler } 4735af32e75SAxel Dörfler } 4745af32e75SAxel Dörfler if (cnt < 0) 4755af32e75SAxel Dörfler { 4765af32e75SAxel Dörfler /* The mantissa so far was fff...f Now increment the 4775af32e75SAxel Dörfler leading digit. Here it is again possible that we 4785af32e75SAxel Dörfler get an overflow. */ 4795af32e75SAxel Dörfler if (leading == '9') 4805af32e75SAxel Dörfler leading = info->spec; 4815af32e75SAxel Dörfler else if (tolower (leading) < 'f') 4825af32e75SAxel Dörfler ++leading; 4835af32e75SAxel Dörfler else 4845af32e75SAxel Dörfler { 485294818c5SAlex Smith leading = '1'; 4865af32e75SAxel Dörfler if (expnegative) 4875af32e75SAxel Dörfler { 488294818c5SAlex Smith exponent -= 4; 489294818c5SAlex Smith if (exponent <= 0) 490294818c5SAlex Smith { 491294818c5SAlex Smith exponent = -exponent; 4925af32e75SAxel Dörfler expnegative = 0; 4935af32e75SAxel Dörfler } 494294818c5SAlex Smith } 4955af32e75SAxel Dörfler else 4965af32e75SAxel Dörfler exponent += 4; 4975af32e75SAxel Dörfler } 4985af32e75SAxel Dörfler } 4995af32e75SAxel Dörfler } 5005af32e75SAxel Dörfler } 5015af32e75SAxel Dörfler else 5025af32e75SAxel Dörfler { 5035af32e75SAxel Dörfler if (precision == -1) 5045af32e75SAxel Dörfler precision = 0; 5055af32e75SAxel Dörfler numend = numstr; 5065af32e75SAxel Dörfler wnumend = wnumstr; 5075af32e75SAxel Dörfler } 5085af32e75SAxel Dörfler 5095af32e75SAxel Dörfler /* Now we can compute the exponent string. */ 5105af32e75SAxel Dörfler expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0); 5115af32e75SAxel Dörfler wexpstr = _itowa_word (exponent, 5125af32e75SAxel Dörfler wexpbuf + sizeof wexpbuf / sizeof (wchar_t), 10, 0); 5135af32e75SAxel Dörfler 5145af32e75SAxel Dörfler /* Now we have all information to compute the size. */ 5155af32e75SAxel Dörfler width -= ((negative || info->showsign || info->space) 5165af32e75SAxel Dörfler /* Sign. */ 5175af32e75SAxel Dörfler + 2 + 1 + 0 + precision + 1 + 1 5185af32e75SAxel Dörfler /* 0x h . hhh P ExpoSign. */ 5195af32e75SAxel Dörfler + ((expbuf + sizeof expbuf) - expstr)); 5205af32e75SAxel Dörfler /* Exponent. */ 5215af32e75SAxel Dörfler 522294818c5SAlex Smith /* Count the decimal point. 523294818c5SAlex Smith A special case when the mantissa or the precision is zero and the `#' 524294818c5SAlex Smith is not given. In this case we must not print the decimal point. */ 5255af32e75SAxel Dörfler if (precision > 0 || info->alt) 5265af32e75SAxel Dörfler width -= wide ? 1 : strlen (decimal); 5275af32e75SAxel Dörfler 528294818c5SAlex Smith if (!info->left && info->pad != '0' && width > 0) 5295af32e75SAxel Dörfler PADN (' ', width); 5305af32e75SAxel Dörfler 5315af32e75SAxel Dörfler if (negative) 5325af32e75SAxel Dörfler outchar ('-'); 5335af32e75SAxel Dörfler else if (info->showsign) 5345af32e75SAxel Dörfler outchar ('+'); 5355af32e75SAxel Dörfler else if (info->space) 5365af32e75SAxel Dörfler outchar (' '); 5375af32e75SAxel Dörfler 5385af32e75SAxel Dörfler outchar ('0'); 5395af32e75SAxel Dörfler if ('X' - 'A' == 'x' - 'a') 5405af32e75SAxel Dörfler outchar (info->spec + ('x' - 'a')); 5415af32e75SAxel Dörfler else 5425af32e75SAxel Dörfler outchar (info->spec == 'A' ? 'X' : 'x'); 543294818c5SAlex Smith 544294818c5SAlex Smith if (!info->left && info->pad == '0' && width > 0) 545294818c5SAlex Smith PADN ('0', width); 546294818c5SAlex Smith 5475af32e75SAxel Dörfler outchar (leading); 5485af32e75SAxel Dörfler 5495af32e75SAxel Dörfler if (precision > 0 || info->alt) 5505af32e75SAxel Dörfler { 5515af32e75SAxel Dörfler const wchar_t *wtmp = &decimalwc; 5525af32e75SAxel Dörfler PRINT (decimal, wtmp, wide ? 1 : strlen (decimal)); 5535af32e75SAxel Dörfler } 5545af32e75SAxel Dörfler 5555af32e75SAxel Dörfler if (precision > 0) 5565af32e75SAxel Dörfler { 5575af32e75SAxel Dörfler ssize_t tofill = precision - (numend - numstr); 5585af32e75SAxel Dörfler PRINT (numstr, wnumstr, MIN (numend - numstr, precision)); 5595af32e75SAxel Dörfler if (tofill > 0) 5605af32e75SAxel Dörfler PADN ('0', tofill); 5615af32e75SAxel Dörfler } 5625af32e75SAxel Dörfler 5635af32e75SAxel Dörfler if ('P' - 'A' == 'p' - 'a') 5645af32e75SAxel Dörfler outchar (info->spec + ('p' - 'a')); 5655af32e75SAxel Dörfler else 5665af32e75SAxel Dörfler outchar (info->spec == 'A' ? 'P' : 'p'); 5675af32e75SAxel Dörfler 5685af32e75SAxel Dörfler outchar (expnegative ? '-' : '+'); 5695af32e75SAxel Dörfler 5705af32e75SAxel Dörfler PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr); 5715af32e75SAxel Dörfler 5725af32e75SAxel Dörfler if (info->left && info->pad != '0' && width > 0) 5735af32e75SAxel Dörfler PADN (info->pad, width); 5745af32e75SAxel Dörfler 5755af32e75SAxel Dörfler return done; 5765af32e75SAxel Dörfler } 577