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)
52ssize_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 \
102do {									      \
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
172int
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