1 | /* Print floating point number in hexadecimal notation according to ISO C99. |
2 | Copyright (C) 1997-2022 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #define PRINT_FPHEX_LONG_DOUBLE \ |
20 | do { \ |
21 | /* We have 105 bits of mantissa plus one implicit digit. Since \ |
22 | 106 bits are representable without rest using hexadecimal \ |
23 | digits we use only the implicit digits for the number before \ |
24 | the decimal point. */ \ |
25 | unsigned long long int num0, num1; \ |
26 | unsigned long long hi, lo; \ |
27 | int ediff; \ |
28 | union ibm_extended_long_double u; \ |
29 | u.ld = fpnum.ldbl; \ |
30 | \ |
31 | assert (sizeof (long double) == 16); \ |
32 | \ |
33 | lo = ((long long)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; \ |
34 | hi = ((long long)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; \ |
35 | lo <<= 7; /* pre-shift lo to match ieee854. */ \ |
36 | /* If the lower double is not a denormal or zero then set the hidden \ |
37 | 53rd bit. */ \ |
38 | if (u.d[1].ieee.exponent != 0) \ |
39 | lo |= (1ULL << (52 + 7)); \ |
40 | else \ |
41 | lo <<= 1; \ |
42 | /* The lower double is normalized separately from the upper. We \ |
43 | may need to adjust the lower manitissa to reflect this. */ \ |
44 | ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53; \ |
45 | if (ediff > 63) \ |
46 | lo = 0; \ |
47 | else if (ediff > 0) \ |
48 | lo = lo >> ediff; \ |
49 | else if (ediff < 0) \ |
50 | lo = lo << -ediff; \ |
51 | if (u.d[0].ieee.negative != u.d[1].ieee.negative \ |
52 | && lo != 0) \ |
53 | { \ |
54 | lo = (1ULL << 60) - lo; \ |
55 | if (hi == 0L) \ |
56 | { \ |
57 | /* we have a borrow from the hidden bit, so shift left 1. */ \ |
58 | hi = 0xffffffffffffeLL | (lo >> 59); \ |
59 | lo = 0xfffffffffffffffLL & (lo << 1); \ |
60 | u.d[0].ieee.exponent--; \ |
61 | } \ |
62 | else \ |
63 | hi--; \ |
64 | } \ |
65 | num1 = (hi << 60) | lo; \ |
66 | num0 = hi >> 4; \ |
67 | \ |
68 | zero_mantissa = (num0|num1) == 0; \ |
69 | \ |
70 | if (sizeof (unsigned long int) > 6) \ |
71 | { \ |
72 | numstr = _itoa_word (num1, numbuf + sizeof numbuf, 16, \ |
73 | info->spec == 'A'); \ |
74 | wnumstr = _itowa_word (num1, \ |
75 | wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\ |
76 | 16, info->spec == 'A'); \ |
77 | } \ |
78 | else \ |
79 | { \ |
80 | numstr = _itoa (num1, numbuf + sizeof numbuf, 16, \ |
81 | info->spec == 'A'); \ |
82 | wnumstr = _itowa (num1, \ |
83 | wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \ |
84 | 16, info->spec == 'A'); \ |
85 | } \ |
86 | \ |
87 | while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \ |
88 | { \ |
89 | *--numstr = '0'; \ |
90 | *--wnumstr = L'0'; \ |
91 | } \ |
92 | \ |
93 | if (sizeof (unsigned long int) > 6) \ |
94 | { \ |
95 | numstr = _itoa_word (num0, numstr, 16, info->spec == 'A'); \ |
96 | wnumstr = _itowa_word (num0, wnumstr, 16, info->spec == 'A'); \ |
97 | } \ |
98 | else \ |
99 | { \ |
100 | numstr = _itoa (num0, numstr, 16, info->spec == 'A'); \ |
101 | wnumstr = _itowa (num0, wnumstr, 16, info->spec == 'A'); \ |
102 | } \ |
103 | \ |
104 | /* Fill with zeroes. */ \ |
105 | while (numstr > numbuf + (sizeof numbuf - 112 / 4)) \ |
106 | { \ |
107 | *--numstr = '0'; \ |
108 | *--wnumstr = L'0'; \ |
109 | } \ |
110 | \ |
111 | leading = u.d[0].ieee.exponent == 0 ? '0' : '1'; \ |
112 | \ |
113 | exponent = u.d[0].ieee.exponent; \ |
114 | \ |
115 | if (exponent == 0) \ |
116 | { \ |
117 | if (zero_mantissa) \ |
118 | expnegative = 0; \ |
119 | else \ |
120 | { \ |
121 | /* This is a denormalized number. */ \ |
122 | expnegative = 1; \ |
123 | exponent = IEEE754_DOUBLE_BIAS - 1; \ |
124 | } \ |
125 | } \ |
126 | else if (exponent >= IEEE754_DOUBLE_BIAS) \ |
127 | { \ |
128 | expnegative = 0; \ |
129 | exponent -= IEEE754_DOUBLE_BIAS; \ |
130 | } \ |
131 | else \ |
132 | { \ |
133 | expnegative = 1; \ |
134 | exponent = -(exponent - IEEE754_DOUBLE_BIAS); \ |
135 | } \ |
136 | } while (0) |
137 | |
138 | #include <stdio-common/printf_fphex.c> |
139 | |