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
__printf_fphex(FILE * fp,const struct printf_info * info,const void * const * args)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