1 /* Print floating point number in hexadecimal notation according to ISO C99. 2 Copyright (C) 1997-2002,2004,2006 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, write to the Free 18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307 USA. */ 20 21 #include <ctype.h> 22 #include <ieee754.h> 23 #include <math.h> 24 #include <printf.h> 25 #include <stdlib.h> 26 #include <stdio.h> 27 #include <string.h> 28 #include <wchar.h> 29 #include "_itoa.h" 30 #include "_itowa.h" 31 #include <locale/localeinfo.h> 32 33 /* #define NDEBUG 1*/ /* Undefine this for debugging assertions. */ 34 #include <assert.h> 35 36 int __printf_fphex (FILE *fp, const struct printf_info *info, 37 const void *const *args); 38 39 /* This defines make it possible to use the same code for GNU C library and 40 the GNU I/O library. */ 41 #ifdef USE_IN_LIBIO 42 # include <libioP.h> 43 # define PUT(f, s, n) _IO_sputn (f, s, n) 44 # define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n)) 45 /* We use this file GNU C library and GNU I/O library. So make 46 names equal. */ 47 # undef putc 48 # define putc(c, f) (wide \ 49 ? (int)_IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f)) 50 # define size_t _IO_size_t 51 # define FILE _IO_FILE 52 #else /* ! USE_IN_LIBIO */ 53 # define PUT(f, s, n) fwrite (s, 1, n, f) 54 # define PAD(f, c, n) __printf_pad (f, c, n) 55 ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c. */ 56 #endif /* USE_IN_LIBIO */ 57 58 /* Macros for doing the actual output. */ 59 60 #define outchar(ch) \ 61 do \ 62 { \ 63 register const int outc = (ch); \ 64 if (putc (outc, fp) == EOF) \ 65 return -1; \ 66 ++done; \ 67 } while (0) 68 69 #define PRINT(ptr, wptr, len) \ 70 do \ 71 { \ 72 register size_t outlen = (len); \ 73 if (wide) \ 74 while (outlen-- > 0) \ 75 outchar (*wptr++); \ 76 else \ 77 while (outlen-- > 0) \ 78 outchar (*ptr++); \ 79 } while (0) 80 81 #define PADN(ch, len) \ 82 do \ 83 { \ 84 if (PAD (fp, ch, len) != len) \ 85 return -1; \ 86 done += len; \ 87 } \ 88 while (0) 89 90 #ifndef MIN 91 # define MIN(a,b) ((a)<(b)?(a):(b)) 92 #endif 93 94 95 96 #if defined(__x86_64__) || defined(__i386__) 97 98 /* sysdeps/x86_64/fpu/printf_fphex.c */ 99 100 #ifndef LONG_DOUBLE_DENORM_BIAS 101 # define LONG_DOUBLE_DENORM_BIAS (IEEE854_LONG_DOUBLE_BIAS - 1) 102 #endif 103 104 #define PRINT_FPHEX_LONG_DOUBLE \ 105 do { \ 106 /* The "strange" 80 bit format on ix86 and m68k has an explicit \ 107 leading digit in the 64 bit mantissa. */ \ 108 unsigned long long int num; \ 109 \ 110 \ 111 num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \ 112 | fpnum.ldbl.ieee.mantissa1); \ 113 \ 114 zero_mantissa = num == 0; \ 115 \ 116 if (sizeof (unsigned long int) > 6) \ 117 { \ 118 numstr = _itoa_word (num, numbuf + sizeof numbuf, 16, \ 119 info->spec == 'A'); \ 120 wnumstr = _itowa_word (num, \ 121 wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\ 122 16, info->spec == 'A'); \ 123 } \ 124 else \ 125 { \ 126 numstr = _itoa (num, numbuf + sizeof numbuf, 16, info->spec == 'A');\ 127 wnumstr = _itowa (num, \ 128 wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \ 129 16, info->spec == 'A'); \ 130 } \ 131 \ 132 /* Fill with zeroes. */ \ 133 while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \ 134 { \ 135 *--numstr = '0'; \ 136 *--wnumstr = L'0'; \ 137 } \ 138 \ 139 /* We use a full nibble for the leading digit. */ \ 140 leading = *numstr++; \ 141 wnumstr++; \ 142 \ 143 /* We have 3 bits from the mantissa in the leading nibble. \ 144 Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \ 145 exponent = fpnum.ldbl.ieee.exponent; \ 146 \ 147 if (exponent == 0) \ 148 { \ 149 if (zero_mantissa) \ 150 expnegative = 0; \ 151 else \ 152 { \ 153 /* This is a denormalized number. */ \ 154 expnegative = 1; \ 155 /* This is a hook for the m68k long double format, where the \ 156 exponent bias is the same for normalized and denormalized \ 157 numbers. */ \ 158 exponent = LONG_DOUBLE_DENORM_BIAS + 3; \ 159 } \ 160 } \ 161 else if (exponent >= IEEE854_LONG_DOUBLE_BIAS + 3) \ 162 { \ 163 expnegative = 0; \ 164 exponent -= IEEE854_LONG_DOUBLE_BIAS + 3; \ 165 } \ 166 else \ 167 { \ 168 expnegative = 1; \ 169 exponent = -(exponent - (IEEE854_LONG_DOUBLE_BIAS + 3)); \ 170 } \ 171 } while (0) 172 173 #endif /* __x86_64__ || __i386__ */ 174 175 176 int 177 __printf_fphex (FILE *fp, 178 const struct printf_info *info, 179 const void *const *args) 180 { 181 /* The floating-point value to output. */ 182 union 183 { 184 union ieee754_double dbl; 185 union ieee854_long_double ldbl; 186 } 187 fpnum; 188 189 /* Locale-dependent representation of decimal point. */ 190 const char *decimal; 191 wchar_t decimalwc; 192 193 /* "NaN" or "Inf" for the special cases. */ 194 const char *special = NULL; 195 const wchar_t *wspecial = NULL; 196 197 /* Buffer for the generated number string for the mantissa. The 198 maximal size for the mantissa is 128 bits. */ 199 char numbuf[32]; 200 char *numstr=""; 201 char *numend; 202 wchar_t wnumbuf[32]; 203 wchar_t *wnumstr=L""; 204 wchar_t *wnumend; 205 int negative; 206 207 /* The maximal exponent of two in decimal notation has 5 digits. */ 208 char expbuf[5]; 209 char *expstr; 210 wchar_t wexpbuf[5]; 211 wchar_t *wexpstr; 212 int expnegative = 0; 213 int exponent = 0; 214 215 /* Non-zero is mantissa is zero. */ 216 int zero_mantissa = 1; 217 218 /* The leading digit before the decimal point. */ 219 char leading = '0'; 220 221 /* Precision. */ 222 int precision = info->prec; 223 224 /* Width. */ 225 int width = info->width; 226 227 /* Number of characters written. */ 228 int done = 0; 229 230 /* Nonzero if this is output on a wide character stream. */ 231 int wide = info->wide; 232 233 234 /* Figure out the decimal point character. */ 235 if (info->extra == 0) 236 { 237 decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); 238 decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC); 239 } 240 else 241 { 242 decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT); 243 decimalwc = _NL_CURRENT_WORD (LC_MONETARY, 244 _NL_MONETARY_DECIMAL_POINT_WC); 245 } 246 /* The decimal point character must never be zero. */ 247 assert (*decimal != '\0' && decimalwc != L'\0'); 248 249 250 /* Fetch the argument value. */ 251 #ifndef __NO_LONG_DOUBLE_MATH 252 if (info->is_long_double && sizeof (long double) > sizeof (double)) 253 { 254 fpnum.ldbl.d = *(const long double *) args[0]; 255 256 /* Check for special values: not a number or infinity. */ 257 if (isnan (fpnum.ldbl.d)) 258 { 259 if (isupper (info->spec)) 260 { 261 special = "NAN"; 262 wspecial = L"NAN"; 263 } 264 else 265 { 266 special = "nan"; 267 wspecial = L"nan"; 268 } 269 negative = 0; 270 } 271 else 272 { 273 if (isinf (fpnum.ldbl.d)) 274 { 275 if (isupper (info->spec)) 276 { 277 special = "INF"; 278 wspecial = L"INF"; 279 } 280 else 281 { 282 special = "inf"; 283 wspecial = L"inf"; 284 } 285 } 286 287 negative = signbit (fpnum.ldbl.d); 288 } 289 } 290 else 291 #endif /* no long double */ 292 { 293 fpnum.dbl.d = *(const double *) args[0]; 294 295 /* Check for special values: not a number or infinity. */ 296 if (isnan (fpnum.dbl.d)) 297 { 298 if (isupper (info->spec)) 299 { 300 special = "NAN"; 301 wspecial = L"NAN"; 302 } 303 else 304 { 305 special = "nan"; 306 wspecial = L"nan"; 307 } 308 negative = 0; 309 } 310 else 311 { 312 if (isinf (fpnum.dbl.d)) 313 { 314 if (isupper (info->spec)) 315 { 316 special = "INF"; 317 wspecial = L"INF"; 318 } 319 else 320 { 321 special = "inf"; 322 wspecial = L"inf"; 323 } 324 } 325 326 negative = signbit (fpnum.dbl.d); 327 } 328 } 329 330 if (special) 331 { 332 int width = info->width; 333 334 if (negative || info->showsign || info->space) 335 --width; 336 width -= 3; 337 338 if (!info->left && width > 0) 339 PADN (' ', width); 340 341 if (negative) 342 outchar ('-'); 343 else if (info->showsign) 344 outchar ('+'); 345 else if (info->space) 346 outchar (' '); 347 348 PRINT (special, wspecial, 3); 349 350 if (info->left && width > 0) 351 PADN (' ', width); 352 353 return done; 354 } 355 356 if (info->is_long_double == 0 || sizeof (double) == sizeof (long double)) 357 { 358 /* We have 52 bits of mantissa plus one implicit digit. Since 359 52 bits are representable without rest using hexadecimal 360 digits we use only the implicit digits for the number before 361 the decimal point. */ 362 unsigned long long int num; 363 364 num = (((unsigned long long int) fpnum.dbl.ieee.mantissa0) << 32 365 | fpnum.dbl.ieee.mantissa1); 366 367 zero_mantissa = num == 0; 368 369 if (sizeof (unsigned long int) > 6) 370 { 371 wnumstr = _itowa_word (num, wnumbuf + (sizeof wnumbuf) / sizeof (wchar_t), 16, 372 info->spec == 'A'); 373 numstr = _itoa_word (num, numbuf + sizeof numbuf, 16, 374 info->spec == 'A'); 375 } 376 else 377 { 378 wnumstr = _itowa (num, wnumbuf + sizeof wnumbuf / sizeof (wchar_t), 16, 379 info->spec == 'A'); 380 numstr = _itoa (num, numbuf + sizeof numbuf, 16, 381 info->spec == 'A'); 382 } 383 384 /* Fill with zeroes. */ 385 while (wnumstr > wnumbuf + (sizeof wnumbuf - 52) / sizeof (wchar_t)) 386 { 387 *--wnumstr = L'0'; 388 *--numstr = '0'; 389 } 390 391 leading = fpnum.dbl.ieee.exponent == 0 ? '0' : '1'; 392 393 exponent = fpnum.dbl.ieee.exponent; 394 395 if (exponent == 0) 396 { 397 if (zero_mantissa) 398 expnegative = 0; 399 else 400 { 401 /* This is a denormalized number. */ 402 expnegative = 1; 403 exponent = IEEE754_DOUBLE_BIAS - 1; 404 } 405 } 406 else if (exponent >= IEEE754_DOUBLE_BIAS) 407 { 408 expnegative = 0; 409 exponent -= IEEE754_DOUBLE_BIAS; 410 } 411 else 412 { 413 expnegative = 1; 414 exponent = -(exponent - IEEE754_DOUBLE_BIAS); 415 } 416 } 417 #ifdef PRINT_FPHEX_LONG_DOUBLE 418 else 419 PRINT_FPHEX_LONG_DOUBLE; 420 #endif 421 422 /* Look for trailing zeroes. */ 423 if (! zero_mantissa) 424 { 425 wnumend = &wnumbuf[sizeof wnumbuf / sizeof wnumbuf[0]]; 426 numend = &numbuf[sizeof numbuf / sizeof numbuf[0]]; 427 while (wnumend[-1] == L'0') 428 { 429 --wnumend; 430 --numend; 431 } 432 433 if (precision == -1) 434 precision = numend - numstr; 435 else if (precision < numend - numstr 436 && (numstr[precision] > '8' 437 || (('A' < '0' || 'a' < '0') 438 && numstr[precision] < '0') 439 || (numstr[precision] == '8' 440 && (precision + 1 < numend - numstr 441 /* Round to even. */ 442 || (precision > 0 443 && ((numstr[precision - 1] & 1) 444 ^ (isdigit (numstr[precision - 1]) == 0))) 445 || (precision == 0 446 && ((leading & 1) 447 ^ (isdigit (leading) == 0))))))) 448 { 449 /* Round up. */ 450 int cnt = precision; 451 while (--cnt >= 0) 452 { 453 char ch = numstr[cnt]; 454 /* We assume that the digits and the letters are ordered 455 like in ASCII. This is true for the rest of GNU, too. */ 456 if (ch == '9') 457 { 458 wnumstr[cnt] = (wchar_t) info->spec; 459 numstr[cnt] = info->spec; /* This is tricky, 460 think about it! */ 461 break; 462 } 463 else if (tolower (ch) < 'f') 464 { 465 ++numstr[cnt]; 466 ++wnumstr[cnt]; 467 break; 468 } 469 else 470 { 471 numstr[cnt] = '0'; 472 wnumstr[cnt] = L'0'; 473 } 474 } 475 if (cnt < 0) 476 { 477 /* The mantissa so far was fff...f Now increment the 478 leading digit. Here it is again possible that we 479 get an overflow. */ 480 if (leading == '9') 481 leading = info->spec; 482 else if (tolower (leading) < 'f') 483 ++leading; 484 else 485 { 486 leading = '1'; 487 if (expnegative) 488 { 489 exponent -= 4; 490 if (exponent <= 0) 491 { 492 exponent = -exponent; 493 expnegative = 0; 494 } 495 } 496 else 497 exponent += 4; 498 } 499 } 500 } 501 } 502 else 503 { 504 if (precision == -1) 505 precision = 0; 506 numend = numstr; 507 wnumend = wnumstr; 508 } 509 510 /* Now we can compute the exponent string. */ 511 expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0); 512 wexpstr = _itowa_word (exponent, 513 wexpbuf + sizeof wexpbuf / sizeof (wchar_t), 10, 0); 514 515 /* Now we have all information to compute the size. */ 516 width -= ((negative || info->showsign || info->space) 517 /* Sign. */ 518 + 2 + 1 + 0 + precision + 1 + 1 519 /* 0x h . hhh P ExpoSign. */ 520 + ((expbuf + sizeof expbuf) - expstr)); 521 /* Exponent. */ 522 523 /* Count the decimal point. 524 A special case when the mantissa or the precision is zero and the `#' 525 is not given. In this case we must not print the decimal point. */ 526 if (precision > 0 || info->alt) 527 width -= wide ? 1 : strlen (decimal); 528 529 if (!info->left && info->pad != '0' && width > 0) 530 PADN (' ', width); 531 532 if (negative) 533 outchar ('-'); 534 else if (info->showsign) 535 outchar ('+'); 536 else if (info->space) 537 outchar (' '); 538 539 outchar ('0'); 540 if ('X' - 'A' == 'x' - 'a') 541 outchar (info->spec + ('x' - 'a')); 542 else 543 outchar (info->spec == 'A' ? 'X' : 'x'); 544 545 if (!info->left && info->pad == '0' && width > 0) 546 PADN ('0', width); 547 548 outchar (leading); 549 550 if (precision > 0 || info->alt) 551 { 552 const wchar_t *wtmp = &decimalwc; 553 PRINT (decimal, wtmp, wide ? 1 : strlen (decimal)); 554 } 555 556 if (precision > 0) 557 { 558 ssize_t tofill = precision - (numend - numstr); 559 PRINT (numstr, wnumstr, MIN (numend - numstr, precision)); 560 if (tofill > 0) 561 PADN ('0', tofill); 562 } 563 564 if ('P' - 'A' == 'p' - 'a') 565 outchar (info->spec + ('p' - 'a')); 566 else 567 outchar (info->spec == 'A' ? 'P' : 'p'); 568 569 outchar (expnegative ? '-' : '+'); 570 571 PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr); 572 573 if (info->left && info->pad != '0' && width > 0) 574 PADN (info->pad, width); 575 576 return done; 577 } 578