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