]>
Commit | Line | Data |
---|---|---|
f964490f | 1 | /* Print floating point number in hexadecimal notation according to ISO C99. |
04277e02 | 2 | Copyright (C) 1997-2019 Free Software Foundation, Inc. |
f964490f RM |
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 | |
59ba27a6 PE |
17 | License along with the GNU C Library; if not, see |
18 | <http://www.gnu.org/licenses/>. */ | |
f964490f RM |
19 | |
20 | #define PRINT_FPHEX_LONG_DOUBLE \ | |
21 | do { \ | |
22 | /* We have 105 bits of mantissa plus one implicit digit. Since \ | |
23 | 106 bits are representable without rest using hexadecimal \ | |
24 | digits we use only the implicit digits for the number before \ | |
25 | the decimal point. */ \ | |
26 | unsigned long long int num0, num1; \ | |
27 | unsigned long long hi, lo; \ | |
28 | int ediff; \ | |
9605ca6c | 29 | union ibm_extended_long_double u; \ |
1b6adf88 | 30 | u.ld = fpnum.ldbl; \ |
f964490f RM |
31 | \ |
32 | assert (sizeof (long double) == 16); \ | |
33 | \ | |
9605ca6c AM |
34 | lo = ((long long)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; \ |
35 | hi = ((long long)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; \ | |
43b76828 | 36 | lo <<= 7; /* pre-shift lo to match ieee854. */ \ |
1b6adf88 | 37 | /* If the lower double is not a denormal or zero then set the hidden \ |
43b76828 | 38 | 53rd bit. */ \ |
9605ca6c | 39 | if (u.d[1].ieee.exponent != 0) \ |
43b76828 UD |
40 | lo |= (1ULL << (52 + 7)); \ |
41 | else \ | |
42 | lo <<= 1; \ | |
43 | /* The lower double is normalized separately from the upper. We \ | |
44 | may need to adjust the lower manitissa to reflect this. */ \ | |
4cf69995 AM |
45 | ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53; \ |
46 | if (ediff > 63) \ | |
43b76828 | 47 | lo = 0; \ |
4cf69995 AM |
48 | else if (ediff > 0) \ |
49 | lo = lo >> ediff; \ | |
50 | else if (ediff < 0) \ | |
51 | lo = lo << -ediff; \ | |
9605ca6c | 52 | if (u.d[0].ieee.negative != u.d[1].ieee.negative \ |
4cf69995 | 53 | && lo != 0) \ |
f964490f RM |
54 | { \ |
55 | lo = (1ULL << 60) - lo; \ | |
56 | if (hi == 0L) \ | |
57 | { \ | |
58 | /* we have a borrow from the hidden bit, so shift left 1. */ \ | |
59 | hi = 0xffffffffffffeLL | (lo >> 59); \ | |
60 | lo = 0xfffffffffffffffLL & (lo << 1); \ | |
9605ca6c | 61 | u.d[0].ieee.exponent--; \ |
f964490f RM |
62 | } \ |
63 | else \ | |
64 | hi--; \ | |
65 | } \ | |
66 | num1 = (hi << 60) | lo; \ | |
67 | num0 = hi >> 4; \ | |
68 | \ | |
69 | zero_mantissa = (num0|num1) == 0; \ | |
70 | \ | |
71 | if (sizeof (unsigned long int) > 6) \ | |
72 | { \ | |
73 | numstr = _itoa_word (num1, numbuf + sizeof numbuf, 16, \ | |
74 | info->spec == 'A'); \ | |
75 | wnumstr = _itowa_word (num1, \ | |
76 | wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\ | |
77 | 16, info->spec == 'A'); \ | |
78 | } \ | |
79 | else \ | |
80 | { \ | |
81 | numstr = _itoa (num1, numbuf + sizeof numbuf, 16, \ | |
82 | info->spec == 'A'); \ | |
83 | wnumstr = _itowa (num1, \ | |
84 | wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \ | |
85 | 16, info->spec == 'A'); \ | |
86 | } \ | |
87 | \ | |
88 | while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \ | |
89 | { \ | |
90 | *--numstr = '0'; \ | |
91 | *--wnumstr = L'0'; \ | |
92 | } \ | |
93 | \ | |
94 | if (sizeof (unsigned long int) > 6) \ | |
95 | { \ | |
96 | numstr = _itoa_word (num0, numstr, 16, info->spec == 'A'); \ | |
97 | wnumstr = _itowa_word (num0, wnumstr, 16, info->spec == 'A'); \ | |
98 | } \ | |
99 | else \ | |
100 | { \ | |
101 | numstr = _itoa (num0, numstr, 16, info->spec == 'A'); \ | |
102 | wnumstr = _itowa (num0, wnumstr, 16, info->spec == 'A'); \ | |
103 | } \ | |
104 | \ | |
105 | /* Fill with zeroes. */ \ | |
106 | while (numstr > numbuf + (sizeof numbuf - 112 / 4)) \ | |
107 | { \ | |
108 | *--numstr = '0'; \ | |
109 | *--wnumstr = L'0'; \ | |
110 | } \ | |
111 | \ | |
9605ca6c | 112 | leading = u.d[0].ieee.exponent == 0 ? '0' : '1'; \ |
f964490f | 113 | \ |
9605ca6c | 114 | exponent = u.d[0].ieee.exponent; \ |
f964490f RM |
115 | \ |
116 | if (exponent == 0) \ | |
117 | { \ | |
118 | if (zero_mantissa) \ | |
119 | expnegative = 0; \ | |
120 | else \ | |
121 | { \ | |
122 | /* This is a denormalized number. */ \ | |
123 | expnegative = 1; \ | |
9605ca6c | 124 | exponent = IEEE754_DOUBLE_BIAS - 1; \ |
f964490f RM |
125 | } \ |
126 | } \ | |
9605ca6c | 127 | else if (exponent >= IEEE754_DOUBLE_BIAS) \ |
f964490f RM |
128 | { \ |
129 | expnegative = 0; \ | |
9605ca6c | 130 | exponent -= IEEE754_DOUBLE_BIAS; \ |
f964490f RM |
131 | } \ |
132 | else \ | |
133 | { \ | |
134 | expnegative = 1; \ | |
9605ca6c | 135 | exponent = -(exponent - IEEE754_DOUBLE_BIAS); \ |
f964490f RM |
136 | } \ |
137 | } while (0) | |
138 | ||
139 | #include <stdio-common/printf_fphex.c> |