]>
Commit | Line | Data |
---|---|---|
3c57e692 PP |
1 | // std::to_chars implementation for floating-point types -*- C++ -*- |
2 | ||
83ffe9cd | 3 | // Copyright (C) 2020-2023 Free Software Foundation, Inc. |
3c57e692 PP |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
8 | // Free Software Foundation; either version 3, or (at your option) | |
9 | // any later version. | |
10 | ||
11 | // This 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 | |
14 | // GNU General Public License for more details. | |
15 | ||
16 | // Under Section 7 of GPL version 3, you are granted additional | |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
24 | ||
3c57e692 PP |
25 | #include <charconv> |
26 | ||
27 | #include <bit> | |
28 | #include <cfenv> | |
29 | #include <cassert> | |
30 | #include <cmath> | |
31 | #include <cstdio> | |
32 | #include <cstring> | |
d7bab388 PP |
33 | #if __has_include(<langinfo.h>) |
34 | # include <langinfo.h> // for nl_langinfo | |
35 | #endif | |
3c57e692 PP |
36 | #include <optional> |
37 | #include <string_view> | |
38 | #include <type_traits> | |
39 | ||
f90027d1 JW |
40 | #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT |
41 | #ifndef __LONG_DOUBLE_IBM128__ | |
42 | #error "floating_to_chars.cc must be compiled with -mabi=ibmlongdouble" | |
43 | #endif | |
44 | // sprintf for __ieee128 | |
45 | extern "C" int __sprintfieee128(char*, const char*, ...); | |
e5bcbcd0 JJ |
46 | #elif __FLT128_MANT_DIG__ == 113 && __LDBL_MANT_DIG__ != 113 \ |
47 | && defined(__GLIBC_PREREQ) | |
48 | extern "C" int __strfromf128(char*, size_t, const char*, _Float128) | |
b457b779 | 49 | __asm ("strfromf128") |
e5bcbcd0 JJ |
50 | #ifndef _GLIBCXX_HAVE_FLOAT128_MATH |
51 | __attribute__((__weak__)) | |
52 | #endif | |
b457b779 | 53 | ; |
f90027d1 JW |
54 | #endif |
55 | ||
6a31d47e PP |
56 | // This implementation crucially assumes float/double have the |
57 | // IEEE binary32/binary64 formats. | |
66c5f247 JR |
58 | #if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 \ |
59 | /* And it also assumes that uint64_t POW10_SPLIT_2[3133][3] is valid. */\ | |
60 | && __SIZE_WIDTH__ >= 32 | |
6a31d47e | 61 | |
3c57e692 PP |
62 | // Determine the binary format of 'long double'. |
63 | ||
64 | // We support the binary64, float80 (i.e. x86 80-bit extended precision), | |
65 | // binary128, and ibm128 formats. | |
66 | #define LDK_UNSUPPORTED 0 | |
67 | #define LDK_BINARY64 1 | |
68 | #define LDK_FLOAT80 2 | |
69 | #define LDK_BINARY128 3 | |
70 | #define LDK_IBM128 4 | |
71 | ||
72 | #if __LDBL_MANT_DIG__ == __DBL_MANT_DIG__ | |
73 | # define LONG_DOUBLE_KIND LDK_BINARY64 | |
c4f8e568 | 74 | #elif __LDBL_MANT_DIG__ == 64 |
3c57e692 | 75 | # define LONG_DOUBLE_KIND LDK_FLOAT80 |
c4f8e568 PP |
76 | #elif __LDBL_MANT_DIG__ == 113 |
77 | # define LONG_DOUBLE_KIND LDK_BINARY128 | |
78 | #elif __LDBL_MANT_DIG__ == 106 | |
79 | # define LONG_DOUBLE_KIND LDK_IBM128 | |
80 | #else | |
81 | # define LONG_DOUBLE_KIND LDK_UNSUPPORTED | |
3c57e692 | 82 | #endif |
f90027d1 | 83 | |
81341565 JW |
84 | // For now we only support __float128 when it's the powerpc64 __ieee128 type. |
85 | #if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT && __FLT128_MANT_DIG__ == 113 | |
c4f8e568 PP |
86 | // Define overloads of std::to_chars for __float128. |
87 | # define FLOAT128_TO_CHARS 1 | |
f90027d1 | 88 | using F128_type = __float128; |
e5bcbcd0 JJ |
89 | #elif __FLT128_MANT_DIG__ == 113 && __LDBL_MANT_DIG__ != 113 \ |
90 | && defined(__GLIBC_PREREQ) | |
91 | # define FLOAT128_TO_CHARS 1 | |
92 | using F128_type = _Float128; | |
f90027d1 JW |
93 | #else |
94 | using F128_type = void; | |
95 | #endif | |
96 | ||
6f038efd JW |
97 | #include <stdint.h> |
98 | ||
3c57e692 PP |
99 | namespace |
100 | { | |
a38fa1b3 PP |
101 | #if defined __SIZEOF_INT128__ |
102 | using uint128_t = unsigned __int128; | |
c4f8e568 PP |
103 | #else |
104 | # include "uint128_t.h" | |
a38fa1b3 PP |
105 | #endif |
106 | ||
3c57e692 PP |
107 | namespace ryu |
108 | { | |
109 | #include "ryu/common.h" | |
110 | #include "ryu/digit_table.h" | |
111 | #include "ryu/d2s_intrinsics.h" | |
112 | #include "ryu/d2s_full_table.h" | |
113 | #include "ryu/d2fixed_full_table.h" | |
114 | #include "ryu/f2s_intrinsics.h" | |
115 | #include "ryu/d2s.c" | |
116 | #include "ryu/d2fixed.c" | |
117 | #include "ryu/f2s.c" | |
118 | ||
3c57e692 PP |
119 | namespace generic128 |
120 | { | |
121 | // Put the generic Ryu bits in their own namespace to avoid name conflicts. | |
122 | # include "ryu/generic_128.h" | |
123 | # include "ryu/ryu_generic_128.h" | |
124 | # include "ryu/generic_128.c" | |
125 | } // namespace generic128 | |
126 | ||
127 | using generic128::floating_decimal_128; | |
128 | using generic128::generic_binary_to_decimal; | |
129 | ||
130 | int | |
131 | to_chars(const floating_decimal_128 v, char* const result) | |
132 | { return generic128::generic_to_chars(v, result); } | |
3c57e692 PP |
133 | } // namespace ryu |
134 | ||
135 | // A traits class that contains pertinent information about the binary | |
136 | // format of each of the floating-point types we support. | |
137 | template<typename T> | |
138 | struct floating_type_traits | |
139 | { }; | |
140 | ||
141 | template<> | |
142 | struct floating_type_traits<float> | |
143 | { | |
3c57e692 PP |
144 | static constexpr int mantissa_bits = 23; |
145 | static constexpr int exponent_bits = 8; | |
146 | static constexpr bool has_implicit_leading_bit = true; | |
147 | using mantissa_t = uint32_t; | |
148 | using shortest_scientific_t = ryu::floating_decimal_32; | |
149 | ||
150 | static constexpr uint64_t pow10_adjustment_tab[] | |
151 | = { 0b0000000000011101011100110101100101101110000000000000000000000000 }; | |
152 | }; | |
153 | ||
154 | template<> | |
155 | struct floating_type_traits<double> | |
156 | { | |
3c57e692 PP |
157 | static constexpr int mantissa_bits = 52; |
158 | static constexpr int exponent_bits = 11; | |
159 | static constexpr bool has_implicit_leading_bit = true; | |
160 | using mantissa_t = uint64_t; | |
161 | using shortest_scientific_t = ryu::floating_decimal_64; | |
162 | ||
163 | static constexpr uint64_t pow10_adjustment_tab[] | |
164 | = { 0b0000000000000000000000011000110101110111000001100101110000111100, | |
165 | 0b0111100011110101011000011110000000110110010101011000001110011111, | |
166 | 0b0101101100000000011100100100111100110110110100010001010101110000, | |
167 | 0b0011110010111000101111110101100011101100010001010000000101100111, | |
168 | 0b0001010000011001011100100001010000010101101000001101000000000000 }; | |
169 | }; | |
170 | ||
f90027d1 JW |
171 | #if LONG_DOUBLE_KIND == LDK_BINARY128 || defined FLOAT128_TO_CHARS |
172 | // Traits for the IEEE binary128 format. | |
173 | struct floating_type_traits_binary128 | |
174 | { | |
175 | static constexpr int mantissa_bits = 112; | |
176 | static constexpr int exponent_bits = 15; | |
177 | static constexpr bool has_implicit_leading_bit = true; | |
a38fa1b3 | 178 | using mantissa_t = uint128_t; |
f90027d1 JW |
179 | using shortest_scientific_t = ryu::floating_decimal_128; |
180 | ||
181 | static constexpr uint64_t pow10_adjustment_tab[] | |
182 | = { 0b0000000000000000000000000000000000000000000000000100000010000000, | |
183 | 0b1011001111110100000100010101101110011100100110000110010110011000, | |
184 | 0b1010100010001101111111000000001101010010100010010000111011110111, | |
185 | 0b1011111001110001111000011111000010110111000111110100101010100101, | |
186 | 0b0110100110011110011011000011000010011001110001001001010011100011, | |
187 | 0b0000011111110010101111101011101010000110011111100111001110100111, | |
188 | 0b0100010101010110000010111011110100000010011001001010001110111101, | |
189 | 0b1101110111000010001101100000110100000111001001101011000101011011, | |
190 | 0b0100111011101101010000001101011000101100101110010010110000101011, | |
191 | 0b0100000110111000000110101000010011101000110100010110000011101101, | |
192 | 0b1011001101001000100001010001100100001111011101010101110001010110, | |
193 | 0b1000000001000000101001110010110010001111101101010101001100000110, | |
194 | 0b0101110110100110000110000001001010111110001110010000111111010011, | |
195 | 0b1010001111100111000100011100100100111100100101000001011001000111, | |
196 | 0b1010011000011100110101100111001011100101111111100001110100000100, | |
197 | 0b1100011100100010100000110001001010000000100000001001010111011101, | |
198 | 0b0101110000100011001111101101000000100110000010010111010001111010, | |
199 | 0b0100111100011010110111101000100110000111001001101100000001111100, | |
200 | 0b1100100100111110101011000100000101011010110111000111110100110101, | |
201 | 0b0110010000010111010100110011000000111010000010111011010110000100, | |
202 | 0b0101001001010010110111010111000101011100000111100111000001110010, | |
203 | 0b1101111111001011101010110001000111011010111101001011010110100100, | |
204 | 0b0001000100110000011111101011001101110010110110010000000011100100, | |
205 | 0b0001000000000101001001001000000000011000100011001110101001001110, | |
206 | 0b0010010010001000111010011011100001000110011011011110110100111000, | |
207 | 0b0000100110101100000111100010100100011100110111011100001111001100, | |
208 | 0b1011111010001110001100000011110111111111100000001011111111101100, | |
209 | 0b0000011100001111010101110000100110111100101101110111101001000001, | |
210 | 0b1100010001110110111100001001001101101000011100000010110101001011, | |
211 | 0b0100101001101011111001011110101101100011011111011100101010101111, | |
212 | 0b0001101001111001110000101101101100001011010001011110011101000010, | |
213 | 0b1111000000101001101111011010110011101110100001011011001011100010, | |
214 | 0b0101001010111101101100001111100010010110001101001000001101100100, | |
215 | 0b0101100101011110001100101011111000111001111001001001101101100001, | |
216 | 0b1111001101010010100100011011000110110010001111000111010001001101, | |
217 | 0b0001110010011000000001000110110111011000011100001000011001110111, | |
218 | 0b0100001011011011011011110011101100100101111111101100101000001110, | |
219 | 0b0101011110111101010111100111101111000101111111111110100011011010, | |
220 | 0b1110101010001001110100000010110111010111111010111110100110010110, | |
221 | 0b1010001111100001001100101000110100001100011100110010000011010111, | |
222 | 0b1111111101101111000100111100000101011000001110011011101010111001, | |
223 | 0b1111101100001110100101111101011001000100000101110000110010100011, | |
224 | 0b1001010110110101101101000101010001010000101011011111010011010000, | |
225 | 0b0111001110110011101001100111000001000100001010110000010000001101, | |
226 | 0b0101111100111110100111011001111001111011011110010111010011101010, | |
227 | 0b1110111000000001100100111001100100110001011011001110101111110111, | |
228 | 0b0001010001001101010111101010011111000011110001101101011001111111, | |
229 | 0b0101000011100011010010001101100001011101011010100110101100100010, | |
230 | 0b0001000101011000100101111100110110000101101101111000110001001011, | |
231 | 0b0101100101001011011000010101000000010100011100101101000010011111, | |
232 | 0b1000010010001011101001011010100010111011110100110011011000100111, | |
233 | 0b1000011011100001010111010111010011101100100010010010100100101001, | |
234 | 0b1001001001010111110101000010111010000000101111010100001010010010, | |
235 | 0b0011011110110010010101111011000001000000000011011111000011111011, | |
236 | 0b1011000110100011001110000001000100000001011100010111010010011110, | |
237 | 0b0111101110110101110111110000011000000100011100011000101101101110, | |
238 | 0b1001100101111011011100011110101011001111100111101010101010110111, | |
239 | 0b1100110010010001100011001111010000000100011101001111011101001111, | |
240 | 0b1000111001111010100101000010000100000001001100101010001011001101, | |
241 | 0b0011101011110000110010100101010100110010100001000010101011111101, | |
242 | 0b1100000000000110000010101011000000011101000110011111100010111111, | |
243 | 0b0010100110000011011100010110111100010110101100110011101110001101, | |
244 | 0b0010111101010011111000111001111100110111111100100011110001101110, | |
245 | 0b1001110111001001101001001001011000010100110001000000100011010110, | |
246 | 0b0011110101100111011011111100001000011001010100111100100101111010, | |
247 | 0b0010001101000011000010100101110000010101101000100110000100001010, | |
248 | 0b0010000010100110010101100101110011101111000111111111001001100001, | |
249 | 0b0100111111011011011011100111111011000010011101101111011111110110, | |
250 | 0b1111111111010110101011101000100101110100001110001001101011100111, | |
251 | 0b1011111101000101110000111100100010111010100001010000010010110010, | |
252 | 0b1111010101001011101011101010000100110110001110111100100110111111, | |
253 | 0b1011001101000001001101000010101010010110010001100001011100011010, | |
254 | 0b0101001011011101010001110100010000010001111100100100100001001101, | |
255 | 0b0010100000111001100011000101100101000001111100111001101000000010, | |
256 | 0b1011001111010101011001000100100110100100110111110100000110111000, | |
257 | 0b0101011111010011100011010010111101110010100001111111100010001001, | |
258 | 0b0010111011101100100000000000001111111010011101100111100001001101, | |
259 | 0b1101000000000000000000000000000000000000000000000000000000000000 }; | |
260 | }; | |
261 | ||
262 | # ifdef FLOAT128_TO_CHARS | |
263 | template<> | |
e5bcbcd0 | 264 | struct floating_type_traits<F128_type> : floating_type_traits_binary128 |
f90027d1 JW |
265 | { }; |
266 | # endif | |
267 | #endif | |
268 | ||
3c57e692 PP |
269 | #if LONG_DOUBLE_KIND == LDK_BINARY64 |
270 | // When long double is equivalent to double, we just forward the long double | |
f90027d1 | 271 | // overloads to the double overloads, so we don't need to define a |
3c57e692 PP |
272 | // floating_type_traits<long double> specialization in this case. |
273 | #elif LONG_DOUBLE_KIND == LDK_FLOAT80 | |
274 | template<> | |
275 | struct floating_type_traits<long double> | |
276 | { | |
277 | static constexpr int mantissa_bits = 64; | |
278 | static constexpr int exponent_bits = 15; | |
279 | static constexpr bool has_implicit_leading_bit = false; | |
280 | using mantissa_t = uint64_t; | |
281 | using shortest_scientific_t = ryu::floating_decimal_128; | |
282 | ||
283 | static constexpr uint64_t pow10_adjustment_tab[] | |
284 | = { 0b0000000000000000000000000000110101011111110100010100110000011101, | |
285 | 0b1001100101001111010011011111101000101111110001011001011101110000, | |
286 | 0b0000101111111011110010001000001010111101011110111111010100011001, | |
287 | 0b0011100000011111001101101011111001111100100010000101001111101001, | |
288 | 0b0100100100000000100111010010101110011000110001101101110011001010, | |
289 | 0b0111100111100010100000010011000010010110101111110101000011110100, | |
290 | 0b1010100111100010011110000011011101101100010110000110101010101010, | |
291 | 0b0000001111001111000000101100111011011000101000110011101100110010, | |
292 | 0b0111000011100100101101010100001101111110101111001000010011111111, | |
293 | 0b0010111000100110100100100010101100111010110001101010010111001000, | |
294 | 0b0000100000010110000011001001000111000001111010100101101000001111, | |
295 | 0b0010101011101000111100001011000010011101000101010010010000101111, | |
296 | 0b1011111011101101110010101011010001111000101000101101011001100011, | |
297 | 0b1010111011011011110111110011001010000010011001110100101101000101, | |
298 | 0b0011000001110110011010010000011100100011001011001100001101010110, | |
299 | 0b0100011111011000111111101000011110000010111110101001000000001001, | |
300 | 0b1110000001110001001101101110011000100000001010000111100010111010, | |
301 | 0b1110001001010011101000111000001000010100110000010110100011110000, | |
302 | 0b0000011010110000110001111000011111000011001101001101001001000110, | |
303 | 0b1010010111001000101001100101010110100100100010010010000101000010, | |
304 | 0b1011001110000111100010100110000011100011111001110111001100000101, | |
305 | 0b0110101001001000010110001000010001010101110101100001111100011001, | |
306 | 0b1111100011110101011110011010101001010010100011000010110001101001, | |
307 | 0b0100000100001000111101011100010011011111011001000000001100011000, | |
308 | 0b1110111111000111100101110111110000000011001110011100011011011001, | |
309 | 0b1100001100100000010001100011011000111011110000110011010101000011, | |
310 | 0b1111111011100111011101001111111000010000001111010111110010000100, | |
311 | 0b1110111001111110101111000101000000001010001110011010001000111010, | |
312 | 0b1000010001011000101111111010110011111101110101101001111000111010, | |
313 | 0b0100000111101001000111011001101000001010111011101001101111000100, | |
314 | 0b0000011100110001000111011100111100110001101111111010110111100000, | |
315 | 0b0000011101011100100110010011110101010100010011110010010111010000, | |
316 | 0b0011011001100111110101111100001001101110101101001110110011110110, | |
317 | 0b1011000101000001110100111001100100111100110011110000000001101000, | |
318 | 0b1011100011110100001001110101010110111001000000001011101001011110, | |
319 | 0b1111001010010010100000010110101010101011101000101000000000001100, | |
320 | 0b1000001111100100111001110101100001010011111111000001000011110000, | |
321 | 0b0001011101001000010000101101111000001110101100110011001100110111, | |
322 | 0b1110011100000010101011011111001010111101111110100000011100000011, | |
323 | 0b1001110110011100101010011110100010110001001110110000101011100110, | |
324 | 0b1001101000100011100111010000011011100001000000110101100100001001, | |
325 | 0b1010111000101000101101010111000010001100001010100011111100000100, | |
326 | 0b0111101000100011000101101011111011100010001101110111001111001011, | |
327 | 0b1110100111010110001110110110000000010110100011110000010001111100, | |
328 | 0b1100010100011010001011001000111001010101011110100101011001000000, | |
329 | 0b0000110001111001100110010110111010101101001101000000000010010101, | |
330 | 0b0001110111101000001111101010110010010000111110111100000111110100, | |
331 | 0b0111110111001001111000110001101101001010101110110101111110000100, | |
332 | 0b0000111110111010101111100010111010011100010110011011011001000001, | |
333 | 0b1010010100100100101110111111111000101100000010111111101101000110, | |
334 | 0b1000100111111101100011001101000110001000000100010101010100001101, | |
335 | 0b1100101010101000111100101100001000110001110010100000000010110101, | |
336 | 0b1010000100111101100100101010010110100010000000110101101110000100, | |
337 | 0b1011111011110001110000100100000000001010111010001101100000100100, | |
338 | 0b0111101101100011001110011100000001000101101101111000100111011111, | |
339 | 0b0100111010010011011001010011110100001100111010010101111111100011, | |
340 | 0b0010001001011000111000001100110111110111110010100011000110110110, | |
341 | 0b0101010110000000010000100000110100111011111101000100000111010010, | |
342 | 0b0110000011011101000001010100110101101110011100110101000000001001, | |
343 | 0b1101100110100000011000001111000100100100110001100110101010101100, | |
344 | 0b0010100101010110010010001010101000011111111111001011001010001111, | |
345 | 0b0111001010001111001100111001010101001000110101000011110000001000, | |
346 | 0b0110010011001001001111110001010010001011010010001101110110110011, | |
347 | 0b0110010100111011000100111000001001101011111001110010111110111111, | |
348 | 0b0101110111001001101100110100101001110010101110011001101110001000, | |
349 | 0b0100110101010111011010001100010111100011010011111001010100111000, | |
350 | 0b0111000110110111011110100100010111000110000110110110110001111110, | |
351 | 0b1000101101010100100100111110100011110110110010011001110011110101, | |
352 | 0b1001101110101001010100111101101011000101000010110101101111110000, | |
353 | 0b0100100101001011011001001011000010001101001010010001010110101000, | |
354 | 0b0010100001001011100110101000010110000111000111000011100101011011, | |
355 | 0b0110111000011001111101101011111010001000000010101000101010011110, | |
356 | 0b1000110110100001111011000001111100001001000000010110010100100100, | |
357 | 0b1001110100011111100111101011010000010101011100101000010010100110, | |
358 | 0b0001010110101110100010101010001110110110100011101010001001111100, | |
359 | 0b1010100101101100000010110011100110100010010000100100001110000100, | |
360 | 0b0001000000010000001010000010100110000001110100111001110111101101, | |
361 | 0b1100000000000000000000000000000000000000000000000000000000000000 }; | |
362 | }; | |
363 | #elif LONG_DOUBLE_KIND == LDK_BINARY128 | |
364 | template<> | |
f90027d1 JW |
365 | struct floating_type_traits<long double> : floating_type_traits_binary128 |
366 | { }; | |
3c57e692 PP |
367 | #elif LONG_DOUBLE_KIND == LDK_IBM128 |
368 | template<> | |
369 | struct floating_type_traits<long double> | |
370 | { | |
371 | static constexpr int mantissa_bits = 105; | |
372 | static constexpr int exponent_bits = 11; | |
373 | static constexpr bool has_implicit_leading_bit = true; | |
a38fa1b3 | 374 | using mantissa_t = uint128_t; |
3c57e692 PP |
375 | using shortest_scientific_t = ryu::floating_decimal_128; |
376 | ||
377 | static constexpr uint64_t pow10_adjustment_tab[] | |
378 | = { 0b0000000000000000000000000000000000000000000000001000000100000000, | |
379 | 0b0000000000000000000100000000000000000000001000000000000000000010, | |
380 | 0b0000100000000000000000001001000000000000000001100100000000000000, | |
381 | 0b0011000000000000000000000000000001110000010000000000000000000000, | |
382 | 0b0000100000000000001000000000000000000000000000100000000000000000 }; | |
383 | }; | |
384 | #endif | |
385 | ||
0ae26533 JJ |
386 | // Wrappers around float for std::{,b}float16_t promoted to float. |
387 | struct floating_type_float16_t | |
388 | { | |
389 | float x; | |
390 | operator float() const { return x; } | |
391 | }; | |
392 | struct floating_type_bfloat16_t | |
393 | { | |
394 | float x; | |
395 | operator float() const { return x; } | |
396 | }; | |
397 | ||
398 | template<> | |
399 | struct floating_type_traits<floating_type_float16_t> | |
400 | { | |
401 | static constexpr int mantissa_bits = 10; | |
402 | static constexpr int exponent_bits = 5; | |
403 | static constexpr bool has_implicit_leading_bit = true; | |
404 | using mantissa_t = uint32_t; | |
405 | using shortest_scientific_t = ryu::floating_decimal_128; | |
406 | ||
407 | static constexpr uint64_t pow10_adjustment_tab[] | |
408 | = { 0 }; | |
409 | }; | |
410 | ||
411 | template<> | |
412 | struct floating_type_traits<floating_type_bfloat16_t> | |
413 | { | |
414 | static constexpr int mantissa_bits = 7; | |
415 | static constexpr int exponent_bits = 8; | |
416 | static constexpr bool has_implicit_leading_bit = true; | |
417 | using mantissa_t = uint32_t; | |
418 | using shortest_scientific_t = ryu::floating_decimal_128; | |
419 | ||
420 | static constexpr uint64_t pow10_adjustment_tab[] | |
421 | = { 0b0000111001110001101010010110100101010010000000000000000000000000 }; | |
422 | }; | |
423 | ||
3c57e692 PP |
424 | // An IEEE-style decomposition of a floating-point value of type T. |
425 | template<typename T> | |
426 | struct ieee_t | |
427 | { | |
428 | typename floating_type_traits<T>::mantissa_t mantissa; | |
429 | uint32_t biased_exponent; | |
430 | bool sign; | |
431 | }; | |
432 | ||
433 | // Decompose the floating-point value into its IEEE components. | |
434 | template<typename T> | |
435 | ieee_t<T> | |
436 | get_ieee_repr(const T value) | |
437 | { | |
a38fa1b3 | 438 | using mantissa_t = typename floating_type_traits<T>::mantissa_t; |
3c57e692 PP |
439 | constexpr int mantissa_bits = floating_type_traits<T>::mantissa_bits; |
440 | constexpr int exponent_bits = floating_type_traits<T>::exponent_bits; | |
441 | constexpr int total_bits = mantissa_bits + exponent_bits + 1; | |
442 | ||
443 | constexpr auto get_uint_t = [] { | |
444 | if constexpr (total_bits <= 32) | |
445 | return uint32_t{}; | |
446 | else if constexpr (total_bits <= 64) | |
447 | return uint64_t{}; | |
3c57e692 | 448 | else if constexpr (total_bits <= 128) |
a38fa1b3 | 449 | return uint128_t{}; |
3c57e692 PP |
450 | }; |
451 | using uint_t = decltype(get_uint_t()); | |
452 | uint_t value_bits = 0; | |
453 | memcpy(&value_bits, &value, sizeof(value)); | |
454 | ||
455 | ieee_t<T> ieee_repr; | |
a38fa1b3 PP |
456 | ieee_repr.mantissa |
457 | = static_cast<mantissa_t>(value_bits & ((uint_t{1} << mantissa_bits) - 1u)); | |
458 | value_bits >>= mantissa_bits; | |
3c57e692 | 459 | ieee_repr.biased_exponent |
a38fa1b3 PP |
460 | = static_cast<uint32_t>(value_bits & ((uint_t{1} << exponent_bits) - 1u)); |
461 | value_bits >>= exponent_bits; | |
462 | ieee_repr.sign = (value_bits & 1) != 0; | |
3c57e692 PP |
463 | return ieee_repr; |
464 | } | |
465 | ||
466 | #if LONG_DOUBLE_KIND == LDK_IBM128 | |
467 | template<> | |
468 | ieee_t<long double> | |
469 | get_ieee_repr(const long double value) | |
470 | { | |
471 | // The layout of __ibm128 isn't compatible with the standard IEEE format. | |
472 | // So we transform it into an IEEE-compatible format, suitable for | |
473 | // consumption by the generic Ryu API, with an 11-bit exponent and 105-bit | |
474 | // mantissa (plus an implicit leading bit). We use the exponent and sign | |
475 | // of the high part, and we merge the mantissa of the high part with the | |
476 | // mantissa (and the implicit leading bit) of the low part. | |
198c5605 PP |
477 | uint64_t value_bits[2] = {}; |
478 | memcpy(value_bits, &value, sizeof(value_bits)); | |
3c57e692 | 479 | |
198c5605 PP |
480 | const uint64_t value_hi = value_bits[0]; |
481 | const uint64_t value_lo = value_bits[1]; | |
3c57e692 PP |
482 | |
483 | uint64_t mantissa_hi = value_hi & ((1ull << 52) - 1); | |
484 | unsigned exponent_hi = (value_hi >> 52) & ((1ull << 11) - 1); | |
485 | const int sign_hi = (value_hi >> 63) & 1; | |
486 | ||
487 | uint64_t mantissa_lo = value_lo & ((1ull << 52) - 1); | |
488 | const unsigned exponent_lo = (value_lo >> 52) & ((1ull << 11) - 1); | |
489 | const int sign_lo = (value_lo >> 63) & 1; | |
490 | ||
491 | { | |
492 | // The following code for adjusting the low-part mantissa to combine | |
493 | // it with the high-part mantissa is taken from the glibc source file | |
494 | // sysdeps/ieee754/ldbl-128ibm/printf_fphex.c. | |
495 | mantissa_lo <<= 7; | |
496 | if (exponent_lo != 0) | |
497 | mantissa_lo |= (1ull << (52 + 7)); | |
498 | else | |
499 | mantissa_lo <<= 1; | |
500 | ||
501 | const int ediff = exponent_hi - exponent_lo - 53; | |
502 | if (ediff > 63) | |
503 | mantissa_lo = 0; | |
504 | else if (ediff > 0) | |
505 | mantissa_lo >>= ediff; | |
506 | else if (ediff < 0) | |
507 | mantissa_lo <<= -ediff; | |
508 | ||
509 | if (sign_lo != sign_hi && mantissa_lo != 0) | |
510 | { | |
511 | mantissa_lo = (1ull << 60) - mantissa_lo; | |
512 | if (mantissa_hi == 0) | |
513 | { | |
514 | mantissa_hi = 0xffffffffffffeLL | (mantissa_lo >> 59); | |
515 | mantissa_lo = 0xfffffffffffffffLL & (mantissa_lo << 1); | |
516 | exponent_hi--; | |
517 | } | |
518 | else | |
519 | mantissa_hi--; | |
520 | } | |
521 | } | |
522 | ||
523 | ieee_t<long double> ieee_repr; | |
a38fa1b3 PP |
524 | ieee_repr.mantissa = ((uint128_t{mantissa_hi} << 64) |
525 | | (uint128_t{mantissa_lo} << 4)) >> 11; | |
3c57e692 PP |
526 | ieee_repr.biased_exponent = exponent_hi; |
527 | ieee_repr.sign = sign_hi; | |
528 | return ieee_repr; | |
529 | } | |
530 | #endif | |
531 | ||
0ae26533 JJ |
532 | template<> |
533 | ieee_t<floating_type_float16_t> | |
534 | get_ieee_repr(const floating_type_float16_t value) | |
535 | { | |
536 | using mantissa_t = typename floating_type_traits<float>::mantissa_t; | |
537 | constexpr int mantissa_bits = floating_type_traits<float>::mantissa_bits; | |
538 | constexpr int exponent_bits = floating_type_traits<float>::exponent_bits; | |
539 | ||
540 | uint32_t value_bits = 0; | |
541 | memcpy(&value_bits, &value.x, sizeof(value)); | |
542 | ||
543 | ieee_t<floating_type_float16_t> ieee_repr; | |
544 | ieee_repr.mantissa | |
545 | = static_cast<mantissa_t>(value_bits & ((uint32_t{1} << mantissa_bits) - 1u)); | |
546 | value_bits >>= mantissa_bits; | |
547 | ieee_repr.biased_exponent | |
548 | = static_cast<uint32_t>(value_bits & ((uint32_t{1} << exponent_bits) - 1u)); | |
549 | value_bits >>= exponent_bits; | |
550 | ieee_repr.sign = (value_bits & 1) != 0; | |
551 | // We have mantissa and biased_exponent from the float (originally | |
552 | // float16_t converted to float). | |
553 | // Transform that to float16_t mantissa and biased_exponent. | |
554 | // If biased_exponent is 0, then value is +-0.0. | |
555 | // If biased_exponent is 0x67..0x70, then it is a float16_t denormal. | |
556 | if (ieee_repr.biased_exponent >= 0x67 | |
557 | && ieee_repr.biased_exponent <= 0x70) | |
558 | { | |
559 | int n = ieee_repr.biased_exponent - 0x67; | |
560 | ieee_repr.mantissa = ((uint32_t{1} << n) | |
561 | | (ieee_repr.mantissa >> (mantissa_bits - n))); | |
562 | ieee_repr.biased_exponent = 0; | |
563 | } | |
564 | // If biased_exponent is 0xff, then it is a float16_t inf or NaN. | |
565 | else if (ieee_repr.biased_exponent == 0xff) | |
566 | { | |
567 | ieee_repr.mantissa >>= 13; | |
568 | ieee_repr.biased_exponent = 0x1f; | |
569 | } | |
570 | // If biased_exponent is 0x71..0x8e, then it is a float16_t normal number. | |
571 | else if (ieee_repr.biased_exponent > 0x70) | |
572 | { | |
573 | ieee_repr.mantissa >>= 13; | |
574 | ieee_repr.biased_exponent -= 0x70; | |
575 | } | |
576 | return ieee_repr; | |
577 | } | |
578 | ||
579 | template<> | |
580 | ieee_t<floating_type_bfloat16_t> | |
581 | get_ieee_repr(const floating_type_bfloat16_t value) | |
582 | { | |
583 | using mantissa_t = typename floating_type_traits<float>::mantissa_t; | |
584 | constexpr int mantissa_bits = floating_type_traits<float>::mantissa_bits; | |
585 | constexpr int exponent_bits = floating_type_traits<float>::exponent_bits; | |
586 | ||
587 | uint32_t value_bits = 0; | |
588 | memcpy(&value_bits, &value.x, sizeof(value)); | |
589 | ||
590 | ieee_t<floating_type_bfloat16_t> ieee_repr; | |
591 | ieee_repr.mantissa | |
592 | = static_cast<mantissa_t>(value_bits & ((uint32_t{1} << mantissa_bits) - 1u)); | |
593 | value_bits >>= mantissa_bits; | |
594 | ieee_repr.biased_exponent | |
595 | = static_cast<uint32_t>(value_bits & ((uint32_t{1} << exponent_bits) - 1u)); | |
596 | value_bits >>= exponent_bits; | |
597 | ieee_repr.sign = (value_bits & 1) != 0; | |
598 | // We have mantissa and biased_exponent from the float (originally | |
599 | // bfloat16_t converted to float). | |
600 | // Transform that to bfloat16_t mantissa and biased_exponent. | |
601 | ieee_repr.mantissa >>= 16; | |
602 | return ieee_repr; | |
603 | } | |
604 | ||
3c57e692 PP |
605 | // Invoke Ryu to obtain the shortest scientific form for the given |
606 | // floating-point number. | |
607 | template<typename T> | |
608 | typename floating_type_traits<T>::shortest_scientific_t | |
609 | floating_to_shortest_scientific(const T value) | |
610 | { | |
611 | if constexpr (std::is_same_v<T, float>) | |
612 | return ryu::floating_to_fd32(value); | |
613 | else if constexpr (std::is_same_v<T, double>) | |
614 | return ryu::floating_to_fd64(value); | |
f90027d1 | 615 | else if constexpr (std::is_same_v<T, long double> |
0ae26533 JJ |
616 | || std::is_same_v<T, F128_type> |
617 | || std::is_same_v<T, floating_type_float16_t> | |
618 | || std::is_same_v<T, floating_type_bfloat16_t>) | |
3c57e692 PP |
619 | { |
620 | constexpr int mantissa_bits | |
621 | = floating_type_traits<T>::mantissa_bits; | |
622 | constexpr int exponent_bits | |
623 | = floating_type_traits<T>::exponent_bits; | |
624 | constexpr bool has_implicit_leading_bit | |
625 | = floating_type_traits<T>::has_implicit_leading_bit; | |
626 | ||
627 | const auto [mantissa, exponent, sign] = get_ieee_repr(value); | |
628 | return ryu::generic_binary_to_decimal(mantissa, exponent, sign, | |
629 | mantissa_bits, exponent_bits, | |
630 | !has_implicit_leading_bit); | |
631 | } | |
3c57e692 PP |
632 | } |
633 | ||
634 | // This subroutine returns true if the shortest scientific form fd is a | |
635 | // positive power of 10, and the floating-point number that has this shortest | |
636 | // scientific form is smaller than this power of 10. | |
637 | // | |
638 | // For instance, the exactly-representable 64-bit number | |
639 | // 99999999999999991611392.0 has the shortest scientific form 1e23, so its | |
640 | // exact value is smaller than its shortest scientific form. | |
641 | // | |
642 | // For these powers of 10 the length of the fixed form is one digit less | |
643 | // than what the scientific exponent suggests. | |
644 | // | |
645 | // This subroutine inspects a lookup table to detect when fd is such a | |
646 | // "rounded up" power of 10. | |
647 | template<typename T> | |
648 | bool | |
649 | is_rounded_up_pow10_p(const typename | |
650 | floating_type_traits<T>::shortest_scientific_t fd) | |
651 | { | |
652 | if (fd.exponent < 0 || fd.mantissa != 1) [[likely]] | |
653 | return false; | |
654 | ||
655 | constexpr auto& pow10_adjustment_tab | |
656 | = floating_type_traits<T>::pow10_adjustment_tab; | |
657 | __glibcxx_assert(fd.exponent/64 < (int)std::size(pow10_adjustment_tab)); | |
658 | return (pow10_adjustment_tab[fd.exponent/64] | |
659 | & (1ull << (63 - fd.exponent%64))); | |
660 | } | |
661 | ||
662 | int | |
663 | get_mantissa_length(const ryu::floating_decimal_32 fd) | |
664 | { return ryu::decimalLength9(fd.mantissa); } | |
665 | ||
666 | int | |
667 | get_mantissa_length(const ryu::floating_decimal_64 fd) | |
668 | { return ryu::decimalLength17(fd.mantissa); } | |
669 | ||
3c57e692 PP |
670 | int |
671 | get_mantissa_length(const ryu::floating_decimal_128 fd) | |
672 | { return ryu::generic128::decimalLength(fd.mantissa); } | |
c4f8e568 PP |
673 | |
674 | #if !defined __SIZEOF_INT128__ | |
675 | // An implementation of base-10 std::to_chars for the uint128_t class type, | |
676 | // used by targets that lack __int128. | |
677 | std::to_chars_result | |
678 | to_chars(char* first, char* const last, uint128_t x) | |
679 | { | |
680 | const int len = ryu::generic128::decimalLength(x); | |
681 | if (last - first < len) | |
682 | return {last, std::errc::value_too_large}; | |
683 | if (x == 0) | |
684 | { | |
685 | *first++ = '0'; | |
686 | return {first, std::errc{}}; | |
687 | } | |
688 | for (int i = 0; i < len; ++i) | |
689 | { | |
690 | first[len - 1 - i] = '0' + static_cast<char>(x % 10); | |
691 | x /= 10; | |
692 | } | |
693 | __glibcxx_assert(x == 0); | |
694 | return {first + len, std::errc{}}; | |
695 | } | |
3c57e692 PP |
696 | #endif |
697 | } // anon namespace | |
698 | ||
699 | namespace std _GLIBCXX_VISIBILITY(default) | |
700 | { | |
701 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
702 | ||
703 | // This subroutine of __floating_to_chars_* handles writing nan, inf and 0 in | |
704 | // all formatting modes. | |
705 | template<typename T> | |
706 | static optional<to_chars_result> | |
707 | __handle_special_value(char* first, char* const last, const T value, | |
708 | const chars_format fmt, const int precision) | |
709 | { | |
710 | __glibcxx_assert(precision >= 0); | |
711 | ||
712 | string_view str; | |
713 | switch (__builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, | |
714 | FP_ZERO, value)) | |
715 | { | |
716 | case FP_INFINITE: | |
717 | str = "-inf"; | |
718 | break; | |
719 | ||
720 | case FP_NAN: | |
721 | str = "-nan"; | |
722 | break; | |
723 | ||
724 | case FP_ZERO: | |
725 | break; | |
726 | ||
727 | default: | |
728 | case FP_SUBNORMAL: | |
729 | case FP_NORMAL: [[likely]] | |
730 | return nullopt; | |
731 | } | |
732 | ||
733 | if (!str.empty()) | |
734 | { | |
735 | // We're formatting +-inf or +-nan. | |
736 | if (!__builtin_signbit(value)) | |
737 | str.remove_prefix(strlen("-")); | |
738 | ||
739 | if (last - first < (int)str.length()) | |
740 | return {{last, errc::value_too_large}}; | |
741 | ||
742 | memcpy(first, &str[0], str.length()); | |
743 | first += str.length(); | |
744 | return {{first, errc{}}}; | |
745 | } | |
746 | ||
747 | // We're formatting 0. | |
748 | __glibcxx_assert(value == 0); | |
749 | const auto orig_first = first; | |
750 | const bool sign = __builtin_signbit(value); | |
751 | int expected_output_length; | |
752 | switch (fmt) | |
753 | { | |
754 | case chars_format::fixed: | |
755 | case chars_format::scientific: | |
756 | case chars_format::hex: | |
757 | expected_output_length = sign + 1; | |
758 | if (precision) | |
759 | expected_output_length += strlen(".") + precision; | |
760 | if (fmt == chars_format::scientific) | |
761 | expected_output_length += strlen("e+00"); | |
762 | else if (fmt == chars_format::hex) | |
763 | expected_output_length += strlen("p+0"); | |
764 | if (last - first < expected_output_length) | |
765 | return {{last, errc::value_too_large}}; | |
766 | ||
767 | if (sign) | |
768 | *first++ = '-'; | |
769 | *first++ = '0'; | |
770 | if (precision) | |
771 | { | |
772 | *first++ = '.'; | |
773 | memset(first, '0', precision); | |
774 | first += precision; | |
775 | } | |
776 | if (fmt == chars_format::scientific) | |
777 | { | |
778 | memcpy(first, "e+00", 4); | |
779 | first += 4; | |
780 | } | |
781 | else if (fmt == chars_format::hex) | |
782 | { | |
783 | memcpy(first, "p+0", 3); | |
784 | first += 3; | |
785 | } | |
786 | break; | |
787 | ||
788 | case chars_format::general: | |
789 | default: // case chars_format{}: | |
790 | expected_output_length = sign + 1; | |
791 | if (last - first < expected_output_length) | |
792 | return {{last, errc::value_too_large}}; | |
793 | ||
794 | if (sign) | |
795 | *first++ = '-'; | |
796 | *first++ = '0'; | |
797 | break; | |
798 | } | |
799 | __glibcxx_assert(first - orig_first == expected_output_length); | |
800 | return {{first, errc{}}}; | |
801 | } | |
802 | ||
0ae26533 JJ |
803 | template<> |
804 | optional<to_chars_result> | |
805 | __handle_special_value<floating_type_float16_t>(char* first, | |
806 | char* const last, | |
807 | const floating_type_float16_t value, | |
808 | const chars_format fmt, | |
809 | const int precision) | |
810 | { | |
811 | return __handle_special_value(first, last, value.x, fmt, precision); | |
812 | } | |
813 | ||
814 | template<> | |
815 | optional<to_chars_result> | |
816 | __handle_special_value<floating_type_bfloat16_t>(char* first, | |
817 | char* const last, | |
818 | const floating_type_bfloat16_t value, | |
819 | const chars_format fmt, | |
820 | const int precision) | |
821 | { | |
822 | return __handle_special_value(first, last, value.x, fmt, precision); | |
823 | } | |
824 | ||
3c57e692 PP |
825 | // This subroutine of the floating-point to_chars overloads performs |
826 | // hexadecimal formatting. | |
827 | template<typename T> | |
828 | static to_chars_result | |
829 | __floating_to_chars_hex(char* first, char* const last, const T value, | |
830 | const optional<int> precision) | |
831 | { | |
832 | if (precision.has_value() && precision.value() < 0) [[unlikely]] | |
833 | // A negative precision argument is treated as if it were omitted. | |
834 | return __floating_to_chars_hex(first, last, value, nullopt); | |
835 | ||
836 | __glibcxx_requires_valid_range(first, last); | |
837 | ||
838 | constexpr int mantissa_bits = floating_type_traits<T>::mantissa_bits; | |
839 | constexpr bool has_implicit_leading_bit | |
840 | = floating_type_traits<T>::has_implicit_leading_bit; | |
841 | constexpr int exponent_bits = floating_type_traits<T>::exponent_bits; | |
842 | constexpr int exponent_bias = (1u << (exponent_bits - 1)) - 1; | |
843 | using mantissa_t = typename floating_type_traits<T>::mantissa_t; | |
844 | constexpr int mantissa_t_width = sizeof(mantissa_t) * __CHAR_BIT__; | |
845 | ||
846 | if (auto result = __handle_special_value(first, last, value, | |
847 | chars_format::hex, | |
848 | precision.value_or(0))) | |
849 | return *result; | |
850 | ||
851 | // Extract the sign, mantissa and exponent from the value. | |
852 | const auto [ieee_mantissa, biased_exponent, sign] = get_ieee_repr(value); | |
853 | const bool is_normal_number = (biased_exponent != 0); | |
854 | ||
855 | // Calculate the unbiased exponent. | |
b65e391d JJ |
856 | int32_t unbiased_exponent = (is_normal_number |
857 | ? biased_exponent - exponent_bias | |
858 | : 1 - exponent_bias); | |
3c57e692 PP |
859 | |
860 | // Shift the mantissa so that its bitwidth is a multiple of 4. | |
861 | constexpr unsigned rounded_mantissa_bits = (mantissa_bits + 3) / 4 * 4; | |
862 | static_assert(mantissa_t_width >= rounded_mantissa_bits); | |
863 | mantissa_t effective_mantissa | |
864 | = ieee_mantissa << (rounded_mantissa_bits - mantissa_bits); | |
865 | if (is_normal_number) | |
866 | { | |
867 | if constexpr (has_implicit_leading_bit) | |
868 | // Restore the mantissa's implicit leading bit. | |
869 | effective_mantissa |= mantissa_t{1} << rounded_mantissa_bits; | |
870 | else | |
871 | // The explicit mantissa bit should already be set. | |
872 | __glibcxx_assert(effective_mantissa & (mantissa_t{1} << (mantissa_bits | |
873 | - 1u))); | |
874 | } | |
b65e391d JJ |
875 | else if (!precision.has_value() && effective_mantissa) |
876 | { | |
877 | // 1.8p-23 is shorter than 0.00cp-14, so if precision is | |
878 | // omitted, try to canonicalize denormals such that they | |
879 | // have the leading bit set. | |
880 | int width = __bit_width(effective_mantissa); | |
881 | int shift = rounded_mantissa_bits - width + has_implicit_leading_bit; | |
882 | unbiased_exponent -= shift; | |
883 | effective_mantissa <<= shift; | |
884 | } | |
3c57e692 PP |
885 | |
886 | // Compute the shortest precision needed to print this value exactly, | |
887 | // disregarding trailing zeros. | |
888 | constexpr int full_hex_precision = (has_implicit_leading_bit | |
889 | ? (mantissa_bits + 3) / 4 | |
890 | // With an explicit leading bit, we | |
891 | // use the four leading nibbles as the | |
892 | // hexit before the decimal point. | |
893 | : (mantissa_bits - 4 + 3) / 4); | |
894 | const int trailing_zeros = __countr_zero(effective_mantissa) / 4; | |
895 | const int shortest_full_precision = full_hex_precision - trailing_zeros; | |
896 | __glibcxx_assert(shortest_full_precision >= 0); | |
897 | ||
898 | int written_exponent = unbiased_exponent; | |
c0e355c7 PP |
899 | int effective_precision = precision.value_or(shortest_full_precision); |
900 | int excess_precision = 0; | |
3c57e692 PP |
901 | if (effective_precision < shortest_full_precision) |
902 | { | |
903 | // When limiting the precision, we need to determine how to round the | |
904 | // least significant printed hexit. The following branchless | |
905 | // bit-level-parallel technique computes whether to round up the | |
906 | // mantissa bit at index N (according to round-to-nearest rules) when | |
907 | // dropping N bits of precision, for each index N in the bit vector. | |
908 | // This technique is borrowed from the MSVC implementation. | |
909 | using bitvec = mantissa_t; | |
910 | const bitvec round_bit = effective_mantissa << 1; | |
911 | const bitvec has_tail_bits = round_bit - 1; | |
912 | const bitvec lsb_bit = effective_mantissa; | |
913 | const bitvec should_round = round_bit & (has_tail_bits | lsb_bit); | |
914 | ||
915 | const int dropped_bits = 4*(full_hex_precision - effective_precision); | |
916 | // Mask out the dropped nibbles. | |
917 | effective_mantissa >>= dropped_bits; | |
918 | effective_mantissa <<= dropped_bits; | |
919 | if (should_round & (mantissa_t{1} << dropped_bits)) | |
920 | { | |
921 | // Round up the least significant nibble. | |
922 | effective_mantissa += mantissa_t{1} << dropped_bits; | |
923 | // Check and adjust for overflow of the leading nibble. When the | |
924 | // type has an implicit leading bit, then the leading nibble | |
925 | // before rounding is either 0 or 1, so it can't overflow. | |
926 | if constexpr (!has_implicit_leading_bit) | |
927 | { | |
928 | // The only supported floating-point type with explicit | |
929 | // leading mantissa bit is LDK_FLOAT80, i.e. x86 80-bit | |
930 | // extended precision, and so we hardcode the below overflow | |
931 | // check+adjustment for this type. | |
932 | static_assert(mantissa_t_width == 64 | |
933 | && rounded_mantissa_bits == 64); | |
934 | if (effective_mantissa == 0) | |
935 | { | |
936 | // We rounded up the least significant nibble and the | |
937 | // mantissa overflowed, e.g f.fcp+10 with precision=1 | |
938 | // became 10.0p+10. Absorb this extra hexit into the | |
939 | // exponent to obtain 1.0p+14. | |
940 | effective_mantissa | |
941 | = mantissa_t{1} << (rounded_mantissa_bits - 4); | |
942 | written_exponent += 4; | |
943 | } | |
944 | } | |
945 | } | |
946 | } | |
c0e355c7 PP |
947 | else |
948 | { | |
949 | excess_precision = effective_precision - shortest_full_precision; | |
950 | effective_precision = shortest_full_precision; | |
951 | } | |
3c57e692 PP |
952 | |
953 | // Compute the leading hexit and mask it out from the mantissa. | |
954 | char leading_hexit; | |
955 | if constexpr (has_implicit_leading_bit) | |
956 | { | |
65857cae | 957 | const auto nibble = unsigned(effective_mantissa >> rounded_mantissa_bits); |
3c57e692 PP |
958 | __glibcxx_assert(nibble <= 2); |
959 | leading_hexit = '0' + nibble; | |
960 | effective_mantissa &= ~(mantissa_t{0b11} << rounded_mantissa_bits); | |
961 | } | |
962 | else | |
963 | { | |
65857cae | 964 | const auto nibble = unsigned(effective_mantissa >> (rounded_mantissa_bits-4)); |
3c57e692 PP |
965 | __glibcxx_assert(nibble < 16); |
966 | leading_hexit = "0123456789abcdef"[nibble]; | |
967 | effective_mantissa &= ~(mantissa_t{0b1111} << (rounded_mantissa_bits-4)); | |
968 | written_exponent -= 3; | |
969 | } | |
970 | ||
971 | // Now before we start writing the string, determine the total length of | |
972 | // the output string and perform a single bounds check. | |
973 | int expected_output_length = sign + 1; | |
c0e355c7 PP |
974 | if (effective_precision + excess_precision > 0) |
975 | expected_output_length += strlen("."); | |
976 | expected_output_length += effective_precision; | |
3c57e692 PP |
977 | const int abs_written_exponent = abs(written_exponent); |
978 | expected_output_length += (abs_written_exponent >= 10000 ? strlen("p+ddddd") | |
979 | : abs_written_exponent >= 1000 ? strlen("p+dddd") | |
980 | : abs_written_exponent >= 100 ? strlen("p+ddd") | |
981 | : abs_written_exponent >= 10 ? strlen("p+dd") | |
982 | : strlen("p+d")); | |
c0e355c7 PP |
983 | if (last - first < expected_output_length |
984 | || last - first - expected_output_length < excess_precision) | |
3c57e692 | 985 | return {last, errc::value_too_large}; |
c0e355c7 | 986 | char* const expected_output_end = first + expected_output_length + excess_precision; |
3c57e692 | 987 | |
3c57e692 PP |
988 | // Write the negative sign and the leading hexit. |
989 | if (sign) | |
990 | *first++ = '-'; | |
991 | *first++ = leading_hexit; | |
992 | ||
c0e355c7 PP |
993 | if (effective_precision + excess_precision > 0) |
994 | *first++ = '.'; | |
995 | ||
3c57e692 PP |
996 | if (effective_precision > 0) |
997 | { | |
3c57e692 PP |
998 | int written_hexits = 0; |
999 | // Extract and mask out the leading nibble after the decimal point, | |
1000 | // write its corresponding hexit, and repeat until the mantissa is | |
1001 | // empty. | |
1002 | int nibble_offset = rounded_mantissa_bits; | |
1003 | if constexpr (!has_implicit_leading_bit) | |
1004 | // We already printed the entire leading hexit. | |
1005 | nibble_offset -= 4; | |
1006 | while (effective_mantissa != 0) | |
1007 | { | |
1008 | nibble_offset -= 4; | |
65857cae | 1009 | const auto nibble = unsigned(effective_mantissa >> nibble_offset); |
3c57e692 PP |
1010 | __glibcxx_assert(nibble < 16); |
1011 | *first++ = "0123456789abcdef"[nibble]; | |
1012 | ++written_hexits; | |
1013 | effective_mantissa &= ~(mantissa_t{0b1111} << nibble_offset); | |
1014 | } | |
1015 | __glibcxx_assert(nibble_offset >= 0); | |
1016 | __glibcxx_assert(written_hexits <= effective_precision); | |
1017 | // Since the mantissa is now empty, every hexit hereafter must be '0'. | |
1018 | if (int remaining_hexits = effective_precision - written_hexits) | |
1019 | { | |
1020 | memset(first, '0', remaining_hexits); | |
1021 | first += remaining_hexits; | |
1022 | } | |
1023 | } | |
1024 | ||
c0e355c7 PP |
1025 | if (excess_precision > 0) |
1026 | { | |
1027 | memset(first, '0', excess_precision); | |
1028 | first += excess_precision; | |
1029 | } | |
1030 | ||
3c57e692 PP |
1031 | // Finally, write the exponent. |
1032 | *first++ = 'p'; | |
1033 | if (written_exponent >= 0) | |
1034 | *first++ = '+'; | |
1035 | const to_chars_result result = to_chars(first, last, written_exponent); | |
c0e355c7 | 1036 | __glibcxx_assert(result.ec == errc{} && result.ptr == expected_output_end); |
3c57e692 PP |
1037 | return result; |
1038 | } | |
1039 | ||
f90027d1 JW |
1040 | namespace |
1041 | { | |
1042 | #pragma GCC diagnostic push | |
1043 | #pragma GCC diagnostic ignored "-Wabi" | |
1044 | template<typename T, typename... Extra> | |
1045 | inline int | |
e5bcbcd0 JJ |
1046 | sprintf_ld(char* buffer, size_t length __attribute__((unused)), |
1047 | const char* format_string, T value, Extra... args) | |
f90027d1 JW |
1048 | { |
1049 | int len; | |
1050 | ||
1051 | #if _GLIBCXX_USE_C99_FENV_TR1 && defined(FE_TONEAREST) | |
1052 | const int saved_rounding_mode = fegetround(); | |
1053 | if (saved_rounding_mode != FE_TONEAREST) | |
1054 | fesetround(FE_TONEAREST); // We want round-to-nearest behavior. | |
1055 | #endif | |
1056 | ||
e5bcbcd0 | 1057 | #ifdef FLOAT128_TO_CHARS |
f90027d1 JW |
1058 | #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT |
1059 | if constexpr (is_same_v<T, __ieee128>) | |
94bfe81a | 1060 | len = __sprintfieee128(buffer, format_string, args..., value); |
f90027d1 | 1061 | else |
e5bcbcd0 JJ |
1062 | #else |
1063 | if constexpr (is_same_v<T, _Float128>) | |
1064 | { | |
1065 | #ifndef _GLIBCXX_HAVE_FLOAT128_MATH | |
1066 | if (&__strfromf128 == nullptr) | |
1067 | len = sprintf(buffer, format_string, args..., (long double)value); | |
1068 | else | |
1069 | #endif | |
1070 | if constexpr (sizeof...(args) == 0) | |
1071 | len = __strfromf128(buffer, length, "%.0f", value); | |
1072 | else | |
1073 | { | |
1074 | // strfromf128 unfortunately doesn't allow .* | |
1075 | char fmt[3 * sizeof(int) + 6]; | |
1076 | sprintf(fmt, "%%.%d%c", args..., int(format_string[4])); | |
1077 | len = __strfromf128(buffer, length, fmt, value); | |
1078 | } | |
1079 | } | |
1080 | else | |
1081 | #endif | |
f90027d1 | 1082 | #endif |
94bfe81a | 1083 | len = sprintf(buffer, format_string, args..., value); |
f90027d1 JW |
1084 | |
1085 | #if _GLIBCXX_USE_C99_FENV_TR1 && defined(FE_TONEAREST) | |
1086 | if (saved_rounding_mode != FE_TONEAREST) | |
1087 | fesetround(saved_rounding_mode); | |
1088 | #endif | |
1089 | ||
1090 | return len; | |
1091 | } | |
1092 | #pragma GCC diagnostic pop | |
1093 | } | |
1094 | ||
3c57e692 PP |
1095 | template<typename T> |
1096 | static to_chars_result | |
1097 | __floating_to_chars_shortest(char* first, char* const last, const T value, | |
1098 | chars_format fmt) | |
1099 | { | |
1100 | if (fmt == chars_format::hex) | |
0ae26533 JJ |
1101 | { |
1102 | // std::bfloat16_t has the same exponent range as std::float32_t | |
1103 | // and so we can avoid instantiation of __floating_to_chars_hex | |
1104 | // for bfloat16_t. Shortest hex will be the same as for float. | |
b65e391d JJ |
1105 | // When we print shortest form even for denormals, we can do it |
1106 | // for std::float16_t as well. | |
1107 | if constexpr (is_same_v<T, floating_type_float16_t> | |
1108 | || is_same_v<T, floating_type_bfloat16_t>) | |
0ae26533 JJ |
1109 | return __floating_to_chars_hex(first, last, value.x, nullopt); |
1110 | else | |
1111 | return __floating_to_chars_hex(first, last, value, nullopt); | |
1112 | } | |
3c57e692 PP |
1113 | |
1114 | __glibcxx_assert(fmt == chars_format::fixed | |
1115 | || fmt == chars_format::scientific | |
1116 | || fmt == chars_format::general | |
1117 | || fmt == chars_format{}); | |
1118 | __glibcxx_requires_valid_range(first, last); | |
1119 | ||
1120 | if (auto result = __handle_special_value(first, last, value, fmt, 0)) | |
1121 | return *result; | |
1122 | ||
1123 | const auto fd = floating_to_shortest_scientific(value); | |
1124 | const int mantissa_length = get_mantissa_length(fd); | |
1125 | const int scientific_exponent = fd.exponent + mantissa_length - 1; | |
1126 | ||
1127 | if (fmt == chars_format::general) | |
1128 | { | |
1129 | // Resolve the 'general' formatting mode as per the specification of | |
1130 | // the 'g' printf output specifier. Since there is no precision | |
1131 | // argument, the default precision of the 'g' specifier, 6, applies. | |
1132 | if (scientific_exponent >= -4 && scientific_exponent < 6) | |
1133 | fmt = chars_format::fixed; | |
1134 | else | |
1135 | fmt = chars_format::scientific; | |
1136 | } | |
1137 | else if (fmt == chars_format{}) | |
1138 | { | |
1139 | // The 'plain' formatting mode resolves to 'scientific' if it yields | |
1140 | // the shorter string, and resolves to 'fixed' otherwise. The | |
1141 | // following lower and upper bounds on the exponent characterize when | |
1142 | // to prefer 'fixed' over 'scientific'. | |
1143 | int lower_bound = -(mantissa_length + 3); | |
1144 | int upper_bound = 5; | |
1145 | if (mantissa_length == 1) | |
1146 | // The decimal point in scientific notation will be omitted in this | |
1147 | // case; tighten the bounds appropriately. | |
1148 | ++lower_bound, --upper_bound; | |
1149 | ||
1150 | if (fd.exponent >= lower_bound && fd.exponent <= upper_bound) | |
1151 | fmt = chars_format::fixed; | |
1152 | else | |
1153 | fmt = chars_format::scientific; | |
1154 | } | |
1155 | ||
1156 | if (fmt == chars_format::scientific) | |
1157 | { | |
1158 | // Calculate the total length of the output string, perform a bounds | |
1159 | // check, and then defer to Ryu's to_chars subroutine. | |
1160 | int expected_output_length = fd.sign + mantissa_length; | |
1161 | if (mantissa_length > 1) | |
1162 | expected_output_length += strlen("."); | |
1163 | const int abs_exponent = abs(scientific_exponent); | |
1164 | expected_output_length += (abs_exponent >= 1000 ? strlen("e+dddd") | |
1165 | : abs_exponent >= 100 ? strlen("e+ddd") | |
1166 | : strlen("e+dd")); | |
1167 | if (last - first < expected_output_length) | |
1168 | return {last, errc::value_too_large}; | |
1169 | ||
1170 | const int output_length = ryu::to_chars(fd, first); | |
1171 | __glibcxx_assert(output_length == expected_output_length); | |
1172 | return {first + output_length, errc{}}; | |
1173 | } | |
1174 | else if (fmt == chars_format::fixed && fd.exponent >= 0) | |
1175 | { | |
1176 | // The Ryu exponent is positive, and so this number's shortest | |
1177 | // representation is a whole number, to be formatted in fixed instead | |
1178 | // of scientific notation "as if by std::printf". This means we may | |
1179 | // need to print more digits of the IEEE mantissa than what the | |
1180 | // shortest scientific form given by Ryu provides. | |
1181 | // | |
1182 | // For instance, the exactly representable number | |
1183 | // 12300000000000001048576.0 has as its shortest scientific | |
1184 | // representation 123e+22, so in this case fd.mantissa is 123 and | |
1185 | // fd.exponent is 22, which doesn't have enough information to format | |
1186 | // the number exactly. So we defer to Ryu's d2fixed_buffered_n with | |
1187 | // precision=0 to format the number in the general case here. | |
1188 | ||
1189 | // To that end, first compute the output length and perform a bounds | |
1190 | // check. | |
1191 | int expected_output_length = fd.sign + mantissa_length + fd.exponent; | |
1192 | if (is_rounded_up_pow10_p<T>(fd)) | |
1193 | --expected_output_length; | |
1194 | if (last - first < expected_output_length) | |
1195 | return {last, errc::value_too_large}; | |
1196 | ||
1197 | // Optimization: if the shortest representation fits inside the IEEE | |
1198 | // mantissa, then the number is certainly exactly-representable and | |
1199 | // its shortest scientific form must be equal to its exact form. So | |
1200 | // we can write the value in fixed form exactly via fd.mantissa and | |
1201 | // fd.exponent. | |
1202 | // | |
1203 | // Taking log2 of both sides of the desired condition | |
1204 | // fd.mantissa * 10^fd.exponent < 2^mantissa_bits | |
1205 | // we get | |
1206 | // log2 fd.mantissa + fd.exponent * log2 10 < mantissa_bits | |
1207 | // where log2 10 is slightly smaller than 10/3=3.333... | |
1208 | // | |
1209 | // After adding some wiggle room due to rounding we get the condition | |
1210 | // value_fits_inside_mantissa_p below. | |
1211 | const int log2_mantissa = __bit_width(fd.mantissa) - 1; | |
1212 | const bool value_fits_inside_mantissa_p | |
1213 | = (log2_mantissa + (fd.exponent*10 + 2) / 3 | |
1214 | < floating_type_traits<T>::mantissa_bits - 2); | |
1215 | if (value_fits_inside_mantissa_p) | |
1216 | { | |
f90027d1 | 1217 | // Print the small exactly-representable number in fixed form by |
3c57e692 PP |
1218 | // writing out fd.mantissa followed by fd.exponent many 0s. |
1219 | if (fd.sign) | |
1220 | *first++ = '-'; | |
1221 | to_chars_result result = to_chars(first, last, fd.mantissa); | |
1222 | __glibcxx_assert(result.ec == errc{}); | |
1223 | memset(result.ptr, '0', fd.exponent); | |
1224 | result.ptr += fd.exponent; | |
1225 | const int output_length = fd.sign + (result.ptr - first); | |
1226 | __glibcxx_assert(output_length == expected_output_length); | |
1227 | return result; | |
1228 | } | |
f90027d1 JW |
1229 | else if constexpr (is_same_v<T, long double> |
1230 | || is_same_v<T, F128_type>) | |
3c57e692 PP |
1231 | { |
1232 | // We can't use d2fixed_buffered_n for types larger than double, | |
1233 | // so we instead format larger types through sprintf. | |
1234 | // TODO: We currently go through an intermediate buffer in order | |
f90027d1 | 1235 | // to accommodate the mandatory null terminator of sprintf, but we |
3c57e692 PP |
1236 | // can avoid this if we use sprintf to write all but the last |
1237 | // digit, and carefully compute and write the last digit | |
1238 | // ourselves. | |
e5bcbcd0 JJ |
1239 | char buffer[expected_output_length + 1]; |
1240 | const int output_length = sprintf_ld(buffer, | |
1241 | expected_output_length + 1, | |
1242 | "%.0Lf", value); | |
3c57e692 PP |
1243 | __glibcxx_assert(output_length == expected_output_length); |
1244 | memcpy(first, buffer, output_length); | |
1245 | return {first + output_length, errc{}}; | |
1246 | } | |
1247 | else | |
1248 | { | |
1249 | // Otherwise, the number is too big, so defer to d2fixed_buffered_n. | |
1250 | const int output_length = ryu::d2fixed_buffered_n(value, 0, first); | |
1251 | __glibcxx_assert(output_length == expected_output_length); | |
1252 | return {first + output_length, errc{}}; | |
1253 | } | |
1254 | } | |
1255 | else if (fmt == chars_format::fixed && fd.exponent < 0) | |
1256 | { | |
1257 | // The Ryu exponent is negative, so fd.mantissa definitely contains | |
1258 | // all of the whole part of the number, and therefore fd.mantissa and | |
1259 | // fd.exponent contain all of the information needed to format the | |
1260 | // number in fixed notation "as if by std::printf" (with precision | |
1261 | // equal to -fd.exponent). | |
22a7e82c | 1262 | const int whole_digits = max<int>(mantissa_length + fd.exponent, 1); |
3c57e692 PP |
1263 | const int expected_output_length |
1264 | = fd.sign + whole_digits + strlen(".") + -fd.exponent; | |
1265 | if (last - first < expected_output_length) | |
1266 | return {last, errc::value_too_large}; | |
1267 | if (mantissa_length <= -fd.exponent) | |
1268 | { | |
1269 | // The magnitude of the number is less than one. Format the | |
1270 | // number appropriately. | |
1271 | const auto orig_first = first; | |
1272 | if (fd.sign) | |
1273 | *first++ = '-'; | |
1274 | *first++ = '0'; | |
1275 | *first++ = '.'; | |
1276 | const int leading_zeros = -fd.exponent - mantissa_length; | |
1277 | memset(first, '0', leading_zeros); | |
1278 | first += leading_zeros; | |
1279 | const to_chars_result result = to_chars(first, last, fd.mantissa); | |
1280 | const int output_length = result.ptr - orig_first; | |
1281 | __glibcxx_assert(output_length == expected_output_length | |
1282 | && result.ec == errc{}); | |
1283 | return result; | |
1284 | } | |
1285 | else | |
1286 | { | |
1287 | // The magnitude of the number is at least one. | |
1288 | const auto orig_first = first; | |
1289 | if (fd.sign) | |
1290 | *first++ = '-'; | |
1291 | to_chars_result result = to_chars(first, last, fd.mantissa); | |
1292 | __glibcxx_assert(result.ec == errc{}); | |
1293 | // Make space for and write the decimal point in the correct spot. | |
1294 | memmove(&result.ptr[fd.exponent+1], &result.ptr[fd.exponent], | |
1295 | -fd.exponent); | |
1296 | result.ptr[fd.exponent] = '.'; | |
1297 | const int output_length = result.ptr + 1 - orig_first; | |
1298 | __glibcxx_assert(output_length == expected_output_length); | |
1299 | ++result.ptr; | |
1300 | return result; | |
1301 | } | |
1302 | } | |
1303 | ||
1304 | __glibcxx_assert(false); | |
cd3964eb | 1305 | __builtin_unreachable(); |
3c57e692 PP |
1306 | } |
1307 | ||
1308 | template<typename T> | |
1309 | static to_chars_result | |
1310 | __floating_to_chars_precision(char* first, char* const last, const T value, | |
1311 | chars_format fmt, const int precision) | |
1312 | { | |
1313 | if (fmt == chars_format::hex) | |
1314 | return __floating_to_chars_hex(first, last, value, precision); | |
1315 | ||
1316 | if (precision < 0) [[unlikely]] | |
1317 | // A negative precision argument is treated as if it were omitted, in | |
1318 | // which case the default precision of 6 applies, as per the printf | |
1319 | // specification. | |
1320 | return __floating_to_chars_precision(first, last, value, fmt, 6); | |
1321 | ||
1322 | __glibcxx_assert(fmt == chars_format::fixed | |
1323 | || fmt == chars_format::scientific | |
1324 | || fmt == chars_format::general); | |
1325 | __glibcxx_requires_valid_range(first, last); | |
1326 | ||
1327 | if (auto result = __handle_special_value(first, last, value, | |
1328 | fmt, precision)) | |
1329 | return *result; | |
1330 | ||
1331 | constexpr int mantissa_bits = floating_type_traits<T>::mantissa_bits; | |
1332 | constexpr int exponent_bits = floating_type_traits<T>::exponent_bits; | |
1333 | constexpr int exponent_bias = (1u << (exponent_bits - 1)) - 1; | |
1334 | ||
1335 | // Extract the sign and exponent from the value. | |
1336 | const auto [mantissa, biased_exponent, sign] = get_ieee_repr(value); | |
1337 | const bool is_normal_number = (biased_exponent != 0); | |
1338 | ||
1339 | // Calculate the unbiased exponent. | |
1340 | const int32_t unbiased_exponent = (is_normal_number | |
1341 | ? biased_exponent - exponent_bias | |
1342 | : 1 - exponent_bias); | |
1343 | ||
1344 | // Obtain trunc(log2(abs(value))), which is just the unbiased exponent. | |
1345 | const int floor_log2_value = unbiased_exponent; | |
1346 | // This is within +-1 of log10(abs(value)). Note that log10 2 is 0.3010.. | |
1347 | const int approx_log10_value = (floor_log2_value >= 0 | |
1348 | ? (floor_log2_value*301 + 999)/1000 | |
1349 | : (floor_log2_value*301 - 999)/1000); | |
1350 | ||
1351 | // Compute (an upper bound of) the number's effective precision when it is | |
1352 | // formatted in scientific and fixed notation. Beyond this precision all | |
1353 | // digits are definitely zero, and this fact allows us to bound the sizes | |
1354 | // of any local output buffers that we may need to use. TODO: Consider | |
1355 | // the number of trailing zero bits in the mantissa to obtain finer upper | |
1356 | // bounds. | |
1357 | // ???: Using "mantissa_bits + 1" instead of just "mantissa_bits" in the | |
1358 | // bounds below is necessary only for __ibm128, it seems. Even though the | |
1359 | // type has 105 bits of precision, printf may output 106 fractional digits | |
1360 | // on some inputs, e.g. 0x1.bcd19f5d720d12a3513e3301028p+0. | |
1361 | const int max_eff_scientific_precision | |
1362 | = (floor_log2_value >= 0 | |
1363 | ? max(mantissa_bits + 1, approx_log10_value + 1) | |
1364 | : -(7*floor_log2_value + 9)/10 + 2 + mantissa_bits + 1); | |
1365 | __glibcxx_assert(max_eff_scientific_precision > 0); | |
1366 | ||
1367 | const int max_eff_fixed_precision | |
1368 | = (floor_log2_value >= 0 | |
1369 | ? mantissa_bits + 1 | |
1370 | : -floor_log2_value + mantissa_bits + 1); | |
1371 | __glibcxx_assert(max_eff_fixed_precision > 0); | |
1372 | ||
1373 | // Ryu doesn't support formatting floating-point types larger than double | |
1374 | // with an explicit precision, so instead we just go through printf. | |
cb0184b6 | 1375 | if constexpr (is_same_v<T, long double> || is_same_v<T, F128_type>) |
3c57e692 PP |
1376 | { |
1377 | int effective_precision; | |
1378 | const char* output_specifier; | |
1379 | if (fmt == chars_format::scientific) | |
1380 | { | |
1381 | effective_precision = min(precision, max_eff_scientific_precision); | |
1382 | output_specifier = "%.*Le"; | |
1383 | } | |
1384 | else if (fmt == chars_format::fixed) | |
1385 | { | |
1386 | effective_precision = min(precision, max_eff_fixed_precision); | |
1387 | output_specifier = "%.*Lf"; | |
1388 | } | |
1389 | else if (fmt == chars_format::general) | |
1390 | { | |
1391 | effective_precision = min(precision, max_eff_scientific_precision); | |
1392 | output_specifier = "%.*Lg"; | |
1393 | } | |
cd3964eb PP |
1394 | else |
1395 | __builtin_unreachable(); | |
3c57e692 PP |
1396 | const int excess_precision = (fmt != chars_format::general |
1397 | ? precision - effective_precision : 0); | |
1398 | ||
1399 | // Since the output of printf is locale-sensitive, we need to be able | |
1400 | // to handle a radix point that's different from '.'. | |
1401 | char radix[6] = {'.', '\0', '\0', '\0', '\0', '\0'}; | |
d7bab388 | 1402 | #ifdef RADIXCHAR |
60cecb2b | 1403 | if (effective_precision > 0) |
3c57e692 PP |
1404 | // ???: Can nl_langinfo() ever return null? |
1405 | if (const char* const radix_ptr = nl_langinfo(RADIXCHAR)) | |
1406 | { | |
1407 | strncpy(radix, radix_ptr, sizeof(radix)-1); | |
1408 | // We accept only radix points which are at most 4 bytes (one | |
1409 | // UTF-8 character) wide. | |
1410 | __glibcxx_assert(radix[4] == '\0'); | |
1411 | } | |
d7bab388 | 1412 | #endif |
3c57e692 PP |
1413 | |
1414 | // Compute straightforward upper bounds on the output length. | |
1415 | int output_length_upper_bound; | |
1416 | if (fmt == chars_format::scientific || fmt == chars_format::general) | |
1417 | output_length_upper_bound = (strlen("-d") + sizeof(radix) | |
1418 | + effective_precision | |
1419 | + strlen("e+dddd")); | |
1420 | else if (fmt == chars_format::fixed) | |
1421 | { | |
1422 | if (approx_log10_value >= 0) | |
1423 | output_length_upper_bound = sign + approx_log10_value + 1; | |
1424 | else | |
1425 | output_length_upper_bound = sign + strlen("0"); | |
1426 | output_length_upper_bound += sizeof(radix) + effective_precision; | |
1427 | } | |
cd3964eb PP |
1428 | else |
1429 | __builtin_unreachable(); | |
3c57e692 PP |
1430 | |
1431 | // Do the sprintf into the local buffer. | |
e5bcbcd0 | 1432 | char buffer[output_length_upper_bound + 1]; |
3c57e692 | 1433 | int output_length |
e5bcbcd0 JJ |
1434 | = sprintf_ld(buffer, output_length_upper_bound + 1, output_specifier, |
1435 | value, effective_precision); | |
3c57e692 PP |
1436 | __glibcxx_assert(output_length <= output_length_upper_bound); |
1437 | ||
1438 | if (effective_precision > 0) | |
1439 | // We need to replace a radix that is different from '.' with '.'. | |
1440 | if (const string_view radix_sv = {radix}; radix_sv != ".") | |
1441 | { | |
1442 | const string_view buffer_sv = {buffer, (size_t)output_length}; | |
1443 | const size_t radix_index = buffer_sv.find(radix_sv); | |
1444 | if (radix_index != string_view::npos) | |
1445 | { | |
1446 | buffer[radix_index] = '.'; | |
1447 | if (radix_sv.length() > 1) | |
1448 | { | |
1449 | memmove(&buffer[radix_index + 1], | |
1450 | &buffer[radix_index + radix_sv.length()], | |
1451 | output_length - radix_index - radix_sv.length()); | |
1452 | output_length -= radix_sv.length() - 1; | |
1453 | } | |
1454 | } | |
1455 | } | |
1456 | ||
1457 | // Copy the string from the buffer over to the output range. | |
c0e355c7 PP |
1458 | if (last - first < output_length |
1459 | || last - first - output_length < excess_precision) | |
3c57e692 PP |
1460 | return {last, errc::value_too_large}; |
1461 | memcpy(first, buffer, output_length); | |
1462 | first += output_length; | |
1463 | ||
1464 | // Add the excess 0s to the result. | |
1465 | if (excess_precision > 0) | |
1466 | { | |
1467 | if (fmt == chars_format::scientific) | |
1468 | { | |
1469 | char* const significand_end | |
1470 | = (output_length >= 6 && first[-6] == 'e' ? &first[-6] | |
1471 | : first[-5] == 'e' ? &first[-5] | |
1472 | : &first[-4]); | |
1473 | __glibcxx_assert(*significand_end == 'e'); | |
1474 | memmove(significand_end + excess_precision, significand_end, | |
1475 | first - significand_end); | |
1476 | memset(significand_end, '0', excess_precision); | |
1477 | first += excess_precision; | |
1478 | } | |
1479 | else if (fmt == chars_format::fixed) | |
1480 | { | |
1481 | memset(first, '0', excess_precision); | |
1482 | first += excess_precision; | |
1483 | } | |
1484 | } | |
1485 | return {first, errc{}}; | |
1486 | } | |
1487 | else if (fmt == chars_format::scientific) | |
1488 | { | |
1489 | const int effective_precision | |
1490 | = min(precision, max_eff_scientific_precision); | |
1491 | const int excess_precision = precision - effective_precision; | |
1492 | ||
1493 | // We can easily compute the output length exactly whenever the | |
1494 | // scientific exponent is far enough away from +-100. But if it's | |
1495 | // near +-100, then our log2 approximation is too coarse (and doesn't | |
1496 | // consider precision-dependent rounding) in order to accurately | |
1497 | // distinguish between a scientific exponent of +-100 and +-99. | |
1498 | const bool scientific_exponent_near_100_p | |
1499 | = abs(abs(floor_log2_value) - 332) <= 4; | |
1500 | ||
1501 | // Compute an upper bound on the output length. TODO: Maybe also | |
1502 | // consider a lower bound on the output length. | |
1503 | int output_length_upper_bound = sign + strlen("d"); | |
1504 | if (effective_precision > 0) | |
1505 | output_length_upper_bound += strlen(".") + effective_precision; | |
1506 | if (scientific_exponent_near_100_p | |
1507 | || (floor_log2_value >= 332 || floor_log2_value <= -333)) | |
1508 | output_length_upper_bound += strlen("e+ddd"); | |
1509 | else | |
1510 | output_length_upper_bound += strlen("e+dd"); | |
1511 | ||
1512 | int output_length; | |
c0e355c7 PP |
1513 | if (last - first >= output_length_upper_bound |
1514 | && last - first - output_length_upper_bound >= excess_precision) | |
3c57e692 PP |
1515 | { |
1516 | // The result will definitely fit into the output range, so we can | |
1517 | // write directly into it. | |
1518 | output_length = ryu::d2exp_buffered_n(value, effective_precision, | |
1519 | first, nullptr); | |
1520 | __glibcxx_assert(output_length == output_length_upper_bound | |
1521 | || (scientific_exponent_near_100_p | |
1522 | && (output_length | |
1523 | == output_length_upper_bound - 1))); | |
1524 | } | |
1525 | else if (scientific_exponent_near_100_p) | |
1526 | { | |
1527 | // Write the result of d2exp_buffered_n into an intermediate | |
1528 | // buffer, do a bounds check, and copy the result into the output | |
1529 | // range. | |
1530 | char buffer[output_length_upper_bound]; | |
1531 | output_length = ryu::d2exp_buffered_n(value, effective_precision, | |
1532 | buffer, nullptr); | |
1533 | __glibcxx_assert(output_length == output_length_upper_bound - 1 | |
1534 | || output_length == output_length_upper_bound); | |
c0e355c7 PP |
1535 | if (last - first < output_length |
1536 | || last - first - output_length < excess_precision) | |
3c57e692 PP |
1537 | return {last, errc::value_too_large}; |
1538 | memcpy(first, buffer, output_length); | |
1539 | } | |
1540 | else | |
1541 | // If the scientific exponent is not near 100, then the upper bound | |
1542 | // is actually the exact length, and so the result will definitely | |
1543 | // not fit into the output range. | |
1544 | return {last, errc::value_too_large}; | |
1545 | first += output_length; | |
1546 | if (excess_precision > 0) | |
1547 | { | |
1548 | // Splice the excess zeros into the result. | |
1549 | char* const significand_end = (first[-5] == 'e' | |
1550 | ? &first[-5] : &first[-4]); | |
1551 | __glibcxx_assert(*significand_end == 'e'); | |
1552 | memmove(significand_end + excess_precision, significand_end, | |
1553 | first - significand_end); | |
1554 | memset(significand_end, '0', excess_precision); | |
1555 | first += excess_precision; | |
1556 | } | |
1557 | return {first, errc{}}; | |
1558 | } | |
1559 | else if (fmt == chars_format::fixed) | |
1560 | { | |
1561 | const int effective_precision | |
1562 | = min(precision, max_eff_fixed_precision); | |
1563 | const int excess_precision = precision - effective_precision; | |
1564 | ||
1565 | // Compute an upper bound on the output length. TODO: Maybe also | |
1566 | // consider a lower bound on the output length. | |
1567 | int output_length_upper_bound; | |
1568 | if (approx_log10_value >= 0) | |
1569 | output_length_upper_bound = sign + approx_log10_value + 1; | |
1570 | else | |
1571 | output_length_upper_bound = sign + strlen("0"); | |
1572 | if (effective_precision > 0) | |
1573 | output_length_upper_bound += strlen(".") + effective_precision; | |
1574 | ||
1575 | int output_length; | |
c0e355c7 PP |
1576 | if (last - first >= output_length_upper_bound |
1577 | && last - first - output_length_upper_bound >= excess_precision) | |
3c57e692 PP |
1578 | { |
1579 | // The result will definitely fit into the output range, so we can | |
1580 | // write directly into it. | |
1581 | output_length = ryu::d2fixed_buffered_n(value, effective_precision, | |
1582 | first); | |
1583 | __glibcxx_assert(output_length <= output_length_upper_bound); | |
1584 | } | |
1585 | else | |
1586 | { | |
1587 | // Write the result of d2fixed_buffered_n into an intermediate | |
1588 | // buffer, do a bounds check, and copy the result into the output | |
1589 | // range. | |
1590 | char buffer[output_length_upper_bound]; | |
1591 | output_length = ryu::d2fixed_buffered_n(value, effective_precision, | |
1592 | buffer); | |
1593 | __glibcxx_assert(output_length <= output_length_upper_bound); | |
c0e355c7 PP |
1594 | if (last - first < output_length |
1595 | || last - first - output_length < excess_precision) | |
3c57e692 PP |
1596 | return {last, errc::value_too_large}; |
1597 | memcpy(first, buffer, output_length); | |
1598 | } | |
1599 | first += output_length; | |
1600 | if (excess_precision > 0) | |
1601 | { | |
1602 | // Append the excess zeros into the result. | |
1603 | memset(first, '0', excess_precision); | |
1604 | first += excess_precision; | |
1605 | } | |
1606 | return {first, errc{}}; | |
1607 | } | |
1608 | else if (fmt == chars_format::general) | |
1609 | { | |
1610 | // Handle the 'general' formatting mode as per C11 printf's %g output | |
1611 | // specifier. Since Ryu doesn't do zero-trimming, we always write to | |
1612 | // an intermediate buffer and manually perform zero-trimming there | |
1613 | // before copying the result over to the output range. | |
1614 | int effective_precision | |
1615 | = min(precision, max_eff_scientific_precision + 1); | |
1616 | const int output_length_upper_bound | |
1617 | = strlen("-d.") + effective_precision + strlen("e+ddd"); | |
1618 | // The four bytes of headroom is to avoid needing to do a memmove when | |
1619 | // rewriting a scientific form such as 1.00e-2 into the equivalent | |
1620 | // fixed form 0.001. | |
1621 | char buffer[4 + output_length_upper_bound]; | |
1622 | ||
1623 | // 7.21.6.1/8: "Let P equal ... 1 if the precision is zero." | |
1624 | if (effective_precision == 0) | |
1625 | effective_precision = 1; | |
1626 | ||
1627 | // Perform a trial formatting in scientific form, and obtain the | |
1628 | // scientific exponent. | |
1629 | int scientific_exponent; | |
1630 | char* buffer_start = buffer + 4; | |
1631 | int output_length | |
1632 | = ryu::d2exp_buffered_n(value, effective_precision - 1, | |
1633 | buffer_start, &scientific_exponent); | |
1634 | __glibcxx_assert(output_length <= output_length_upper_bound); | |
1635 | ||
1636 | // 7.21.6.1/8: "Then, if a conversion with style E would have an | |
1637 | // exponent of X: | |
1638 | // if P > X >= -4, the conversion is with style f and | |
1639 | // precision P - (X + 1). | |
1640 | // otherwise, the conversion is with style e and precision P - 1." | |
1641 | const bool resolve_to_fixed_form | |
1642 | = (scientific_exponent >= -4 | |
1643 | && scientific_exponent < effective_precision); | |
1644 | if (resolve_to_fixed_form) | |
1645 | { | |
1646 | // Rather than invoking d2fixed_buffered_n to reformat the number | |
1647 | // for us from scratch, we can just rewrite the scientific form | |
1648 | // into fixed form in-place. This is safe to do because whenever | |
1649 | // %g resolves to %f, the fixed form will be no larger than the | |
1650 | // corresponding scientific form, and it will also contain the | |
1651 | // same significant digits as the scientific form. | |
1652 | fmt = chars_format::fixed; | |
1653 | if (scientific_exponent < 0) | |
1654 | { | |
1655 | // e.g. buffer_start == "-1.234e-04" | |
1656 | char* leading_digit = &buffer_start[sign]; | |
1657 | leading_digit[1] = leading_digit[0]; | |
1658 | // buffer_start == "-11234e-04" | |
1659 | buffer_start -= -scientific_exponent; | |
1660 | __glibcxx_assert(buffer_start >= buffer); | |
1661 | // buffer_start == "????-11234e-04" | |
1662 | char* head = buffer_start; | |
1663 | if (sign) | |
1664 | *head++ = '-'; | |
1665 | *head++ = '0'; | |
1666 | *head++ = '.'; | |
1667 | memset(head, '0', -scientific_exponent - 1); | |
1668 | // buffer_start == "-0.00011234e-04" | |
1669 | ||
1670 | // Now drop the exponent suffix, and add the leading zeros to | |
1671 | // the output length. | |
1672 | output_length -= strlen("e-0d"); | |
1673 | output_length += -scientific_exponent; | |
1674 | if (effective_precision - 1 == 0) | |
1675 | // The scientific form had no decimal point, but the fixed | |
1676 | // form now does. | |
1677 | output_length += strlen("."); | |
1678 | } | |
1679 | else if (effective_precision == 1) | |
1680 | { | |
1681 | // The scientific exponent must be 0, so the fixed form | |
1682 | // coincides with the scientific form (minus the exponent | |
1683 | // suffix). | |
1684 | __glibcxx_assert(scientific_exponent == 0); | |
1685 | output_length -= strlen("e+dd"); | |
1686 | } | |
1687 | else | |
1688 | { | |
1689 | // We are dealing with a scientific form which has a | |
1690 | // non-empty fractional part and a nonnegative exponent, | |
1691 | // e.g. buffer_start == "1.234e+02". | |
1692 | __glibcxx_assert(effective_precision >= 1); | |
1693 | char* const decimal_point = &buffer_start[sign + 1]; | |
1694 | __glibcxx_assert(*decimal_point == '.'); | |
1695 | memmove(decimal_point, decimal_point+1, | |
1696 | scientific_exponent); | |
1697 | // buffer_start == "123.4e+02" | |
1698 | decimal_point[scientific_exponent] = '.'; | |
1699 | if (scientific_exponent >= 100) | |
1700 | output_length -= strlen("e+ddd"); | |
1701 | else | |
1702 | output_length -= strlen("e+dd"); | |
1703 | if (effective_precision - 1 == scientific_exponent) | |
1704 | output_length -= strlen("."); | |
1705 | } | |
1706 | effective_precision -= 1 + scientific_exponent; | |
1707 | ||
1708 | __glibcxx_assert(output_length <= output_length_upper_bound); | |
1709 | } | |
1710 | else | |
1711 | { | |
1712 | // We're sticking to the scientific form, so keep the output as-is. | |
1713 | fmt = chars_format::scientific; | |
1714 | effective_precision = effective_precision - 1; | |
1715 | } | |
1716 | ||
1717 | // 7.21.6.1/8: "Finally ... any any trailing zeros are removed from | |
1718 | // the fractional portion of the result and the decimal-point | |
1719 | // character is removed if there is no fractional portion remaining." | |
1720 | if (effective_precision > 0) | |
1721 | { | |
1722 | char* decimal_point = nullptr; | |
1723 | if (fmt == chars_format::scientific) | |
1724 | decimal_point = &buffer_start[sign + 1]; | |
1725 | else if (fmt == chars_format::fixed) | |
1726 | decimal_point | |
1727 | = &buffer_start[output_length] - effective_precision - 1; | |
1728 | __glibcxx_assert(*decimal_point == '.'); | |
1729 | ||
1730 | char* const fractional_part_start = decimal_point + 1; | |
1731 | char* fractional_part_end = nullptr; | |
1732 | if (fmt == chars_format::scientific) | |
1733 | { | |
1734 | fractional_part_end = (buffer_start[output_length-5] == 'e' | |
1735 | ? &buffer_start[output_length-5] | |
1736 | : &buffer_start[output_length-4]); | |
1737 | __glibcxx_assert(*fractional_part_end == 'e'); | |
1738 | } | |
1739 | else if (fmt == chars_format::fixed) | |
1740 | fractional_part_end = &buffer_start[output_length]; | |
1741 | ||
1742 | const string_view fractional_part | |
1743 | = {fractional_part_start, (size_t)(fractional_part_end | |
1744 | - fractional_part_start) }; | |
1745 | const size_t last_nonzero_digit_pos | |
1746 | = fractional_part.find_last_not_of('0'); | |
1747 | ||
1748 | char* trim_start; | |
1749 | if (last_nonzero_digit_pos == string_view::npos) | |
1750 | trim_start = decimal_point; | |
1751 | else | |
1752 | trim_start = &fractional_part_start[last_nonzero_digit_pos] + 1; | |
1753 | if (fmt == chars_format::scientific) | |
1754 | memmove(trim_start, fractional_part_end, | |
1755 | &buffer_start[output_length] - fractional_part_end); | |
1756 | output_length -= fractional_part_end - trim_start; | |
1757 | } | |
1758 | ||
1759 | if (last - first < output_length) | |
1760 | return {last, errc::value_too_large}; | |
1761 | ||
1762 | memcpy(first, buffer_start, output_length); | |
1763 | return {first + output_length, errc{}}; | |
1764 | } | |
1765 | ||
1766 | __glibcxx_assert(false); | |
cd3964eb | 1767 | __builtin_unreachable(); |
3c57e692 PP |
1768 | } |
1769 | ||
1770 | // Define the overloads for float. | |
1771 | to_chars_result | |
1772 | to_chars(char* first, char* last, float value) noexcept | |
1773 | { return __floating_to_chars_shortest(first, last, value, chars_format{}); } | |
1774 | ||
1775 | to_chars_result | |
1776 | to_chars(char* first, char* last, float value, chars_format fmt) noexcept | |
1777 | { return __floating_to_chars_shortest(first, last, value, fmt); } | |
1778 | ||
1779 | to_chars_result | |
1780 | to_chars(char* first, char* last, float value, chars_format fmt, | |
1781 | int precision) noexcept | |
1782 | { return __floating_to_chars_precision(first, last, value, fmt, precision); } | |
1783 | ||
1784 | // Define the overloads for double. | |
1785 | to_chars_result | |
1786 | to_chars(char* first, char* last, double value) noexcept | |
1787 | { return __floating_to_chars_shortest(first, last, value, chars_format{}); } | |
1788 | ||
1789 | to_chars_result | |
1790 | to_chars(char* first, char* last, double value, chars_format fmt) noexcept | |
1791 | { return __floating_to_chars_shortest(first, last, value, fmt); } | |
1792 | ||
1793 | to_chars_result | |
1794 | to_chars(char* first, char* last, double value, chars_format fmt, | |
1795 | int precision) noexcept | |
1796 | { return __floating_to_chars_precision(first, last, value, fmt, precision); } | |
1797 | ||
1798 | // Define the overloads for long double. | |
1799 | to_chars_result | |
1800 | to_chars(char* first, char* last, long double value) noexcept | |
1801 | { | |
1802 | if constexpr (LONG_DOUBLE_KIND == LDK_BINARY64 | |
1803 | || LONG_DOUBLE_KIND == LDK_UNSUPPORTED) | |
1804 | return __floating_to_chars_shortest(first, last, static_cast<double>(value), | |
1805 | chars_format{}); | |
1806 | else | |
1807 | return __floating_to_chars_shortest(first, last, value, chars_format{}); | |
1808 | } | |
1809 | ||
1810 | to_chars_result | |
1811 | to_chars(char* first, char* last, long double value, chars_format fmt) noexcept | |
1812 | { | |
1813 | if constexpr (LONG_DOUBLE_KIND == LDK_BINARY64 | |
1814 | || LONG_DOUBLE_KIND == LDK_UNSUPPORTED) | |
1815 | return __floating_to_chars_shortest(first, last, static_cast<double>(value), | |
1816 | fmt); | |
1817 | else | |
1818 | return __floating_to_chars_shortest(first, last, value, fmt); | |
1819 | } | |
1820 | ||
1821 | to_chars_result | |
1822 | to_chars(char* first, char* last, long double value, chars_format fmt, | |
1823 | int precision) noexcept | |
1824 | { | |
1825 | if constexpr (LONG_DOUBLE_KIND == LDK_BINARY64 | |
1826 | || LONG_DOUBLE_KIND == LDK_UNSUPPORTED) | |
1827 | return __floating_to_chars_precision(first, last, static_cast<double>(value), | |
1828 | fmt, | |
1829 | precision); | |
1830 | else | |
1831 | return __floating_to_chars_precision(first, last, value, fmt, precision); | |
1832 | } | |
1833 | ||
f90027d1 | 1834 | #ifdef FLOAT128_TO_CHARS |
e5bcbcd0 | 1835 | #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT |
f90027d1 JW |
1836 | to_chars_result |
1837 | to_chars(char* first, char* last, __float128 value) noexcept | |
1838 | { | |
1839 | return __floating_to_chars_shortest(first, last, value, chars_format{}); | |
1840 | } | |
1841 | ||
1842 | to_chars_result | |
1843 | to_chars(char* first, char* last, __float128 value, chars_format fmt) noexcept | |
1844 | { | |
1845 | return __floating_to_chars_shortest(first, last, value, fmt); | |
1846 | } | |
1847 | ||
1848 | to_chars_result | |
1849 | to_chars(char* first, char* last, __float128 value, chars_format fmt, | |
1850 | int precision) noexcept | |
1851 | { | |
1852 | return __floating_to_chars_precision(first, last, value, fmt, precision); | |
1853 | } | |
e5bcbcd0 JJ |
1854 | #else |
1855 | to_chars_result | |
1856 | to_chars(char* first, char* last, _Float128 value) noexcept | |
1857 | { | |
1858 | return __floating_to_chars_shortest(first, last, value, chars_format{}); | |
1859 | } | |
1860 | ||
1861 | to_chars_result | |
1862 | to_chars(char* first, char* last, _Float128 value, chars_format fmt) noexcept | |
1863 | { | |
1864 | return __floating_to_chars_shortest(first, last, value, fmt); | |
1865 | } | |
1866 | ||
1867 | to_chars_result | |
1868 | to_chars(char* first, char* last, _Float128 value, chars_format fmt, | |
1869 | int precision) noexcept | |
1870 | { | |
1871 | return __floating_to_chars_precision(first, last, value, fmt, precision); | |
1872 | } | |
1873 | #endif | |
f90027d1 JW |
1874 | #endif |
1875 | ||
0ae26533 JJ |
1876 | // Entrypoints for 16-bit floats. |
1877 | [[gnu::cold]] to_chars_result | |
1878 | __to_chars_float16_t(char* first, char* last, float value, | |
1879 | chars_format fmt) noexcept | |
1880 | { | |
1881 | return __floating_to_chars_shortest(first, last, | |
1882 | floating_type_float16_t{ value }, fmt); | |
1883 | } | |
1884 | ||
1885 | [[gnu::cold]] to_chars_result | |
1886 | __to_chars_bfloat16_t(char* first, char* last, float value, | |
1887 | chars_format fmt) noexcept | |
1888 | { | |
1889 | return __floating_to_chars_shortest(first, last, | |
1890 | floating_type_bfloat16_t{ value }, fmt); | |
1891 | } | |
1892 | ||
3c57e692 PP |
1893 | #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT |
1894 | // Map the -mlong-double-64 long double overloads to the double overloads. | |
1895 | extern "C" to_chars_result | |
1896 | _ZSt8to_charsPcS_e(char* first, char* last, double value) noexcept | |
1897 | __attribute__((alias ("_ZSt8to_charsPcS_d"))); | |
1898 | ||
1899 | extern "C" to_chars_result | |
1900 | _ZSt8to_charsPcS_eSt12chars_format(char* first, char* last, double value, | |
1901 | chars_format fmt) noexcept | |
1902 | __attribute__((alias ("_ZSt8to_charsPcS_dSt12chars_format"))); | |
1903 | ||
1904 | extern "C" to_chars_result | |
1905 | _ZSt8to_charsPcS_eSt12chars_formati(char* first, char* last, double value, | |
1906 | chars_format fmt, int precision) noexcept | |
1907 | __attribute__((alias ("_ZSt8to_charsPcS_dSt12chars_formati"))); | |
1908 | #endif | |
1909 | ||
1910 | _GLIBCXX_END_NAMESPACE_VERSION | |
1911 | } // namespace std | |
6a31d47e PP |
1912 | |
1913 | #endif // _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 |