]> gcc.gnu.org Git - gcc.git/blob - libstdc++-v3/src/c++17/floating_from_chars.cc
libstdc++: case-sensitivity in hexfloat std::from_chars [PR105441]
[gcc.git] / libstdc++-v3 / src / c++17 / floating_from_chars.cc
1 // std::from_chars implementation for floating-point types -*- C++ -*-
2
3 // Copyright (C) 2020-2022 Free Software Foundation, Inc.
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
25 //
26 // ISO C++ 14882:2017
27 // 23.2.9 Primitive numeric input conversion [utility.from.chars]
28 //
29
30 // Prefer to use std::pmr::string if possible, which requires the cxx11 ABI.
31 #define _GLIBCXX_USE_CXX11_ABI 1
32
33 #include <array>
34 #include <charconv>
35 #include <bit>
36 #include <string>
37 #include <memory_resource>
38 #include <cfenv>
39 #include <cfloat>
40 #include <cmath>
41 #include <cstdlib>
42 #include <cstring>
43 #include <cctype>
44 #include <locale.h>
45 #include <bits/functexcept.h>
46 #if _GLIBCXX_HAVE_XLOCALE_H
47 # include <xlocale.h>
48 #endif
49
50 #if _GLIBCXX_HAVE_USELOCALE
51 // FIXME: This should be reimplemented so it doesn't use strtod and newlocale.
52 // That will avoid the need for any memory allocation, meaning that the
53 // non-conforming errc::not_enough_memory result cannot happen.
54 # define USE_STRTOD_FOR_FROM_CHARS 1
55 #endif
56
57 #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
58 #ifndef __LONG_DOUBLE_IBM128__
59 #error "floating_from_chars.cc must be compiled with -mabi=ibmlongdouble"
60 #endif
61 // strtold for __ieee128
62 extern "C" __ieee128 __strtoieee128(const char*, char**);
63 #endif
64
65 #if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 \
66 && __SIZE_WIDTH__ >= 32
67 # define USE_LIB_FAST_FLOAT 1
68 # if __LDBL_MANT_DIG__ == __DBL_MANT_DIG__
69 // No need to use strtold.
70 # undef USE_STRTOD_FOR_FROM_CHARS
71 # endif
72 #endif
73
74 #if USE_LIB_FAST_FLOAT
75 # define FASTFLOAT_DEBUG_ASSERT __glibcxx_assert
76 namespace
77 {
78 # include "fast_float/fast_float.h"
79 } // anon namespace
80 #endif
81
82 namespace std _GLIBCXX_VISIBILITY(default)
83 {
84 _GLIBCXX_BEGIN_NAMESPACE_VERSION
85
86 namespace
87 {
88 #if USE_STRTOD_FOR_FROM_CHARS
89 // A memory resource with a static buffer that can be used for small
90 // allocations. At most one allocation using the freestore can be done
91 // if the static buffer is insufficient. The callers below only require
92 // a single allocation, so there's no need for anything more complex.
93 struct buffer_resource : pmr::memory_resource
94 {
95 ~buffer_resource() { if (m_ptr) operator delete(m_ptr, m_bytes); }
96
97 void*
98 do_allocate(size_t bytes, size_t alignment [[maybe_unused]]) override
99 {
100 // Allocate from the buffer if it will fit.
101 if (m_bytes < sizeof(m_buf) && (m_bytes + bytes) <= sizeof(m_buf))
102 return m_buf + std::__exchange(m_bytes, m_bytes + bytes);
103
104 __glibcxx_assert(m_ptr == nullptr);
105
106 m_ptr = operator new(bytes);
107 m_bytes = bytes;
108 return m_ptr;
109 }
110
111 void
112 do_deallocate(void*, size_t, size_t) noexcept override
113 { /* like pmr::monotonic_buffer_resource, do nothing here */ }
114
115 bool
116 do_is_equal(const pmr::memory_resource& other) const noexcept override
117 { return &other == this; }
118
119 static constexpr int guaranteed_capacity() { return sizeof(m_buf); }
120
121 private:
122 char m_buf[512];
123 size_t m_bytes = 0;
124 void* m_ptr = nullptr;
125 };
126
127 #if _GLIBCXX_USE_CXX11_ABI
128 using buffered_string = std::pmr::string;
129 #else
130 using buffered_string = std::string;
131 #endif
132
133 inline bool valid_fmt(chars_format fmt)
134 {
135 return fmt != chars_format{}
136 && ((fmt & chars_format::general) == fmt
137 || (fmt & chars_format::hex) == fmt);
138 }
139
140 constexpr char hex_digits[] = "abcdefABCDEF0123456789";
141 constexpr auto dec_digits = hex_digits + 12;
142
143 // Find initial portion of [first, last) containing a floating-point number.
144 // The string `digits` is either `dec_digits` or `hex_digits`
145 // and `exp` is 'e' or 'p' or '\0'.
146 const char*
147 find_end_of_float(const char* first, const char* last, const char* digits,
148 char exp)
149 {
150 while (first < last && strchr(digits, *first) != nullptr)
151 ++first;
152 if (first < last && *first == '.')
153 {
154 ++first;
155 while (first < last && strchr(digits, *first))
156 ++first;
157 }
158 if (first < last && exp != 0 && std::tolower((unsigned char)*first) == exp)
159 {
160 ++first;
161 if (first < last && (*first == '-' || *first == '+'))
162 ++first;
163 while (first < last && strchr(dec_digits, *first) != nullptr)
164 ++first;
165 }
166 return first;
167 }
168
169 // Determine the prefix of [first, last) that matches the pattern
170 // corresponding to `fmt`.
171 // Returns a NTBS containing the pattern, using `buf` to allocate
172 // additional storage if needed.
173 // Returns a nullptr if a valid pattern is not present.
174 const char*
175 pattern(const char* const first, const char* last,
176 chars_format& fmt, buffered_string& buf)
177 {
178 // fmt has the value of one of the enumerators of chars_format.
179 __glibcxx_assert(valid_fmt(fmt));
180
181 string_view res;
182
183 if (first == last || *first == '+') [[unlikely]]
184 return nullptr;
185
186 const int neg = (*first == '-');
187
188 if (std::memchr("iInN", (unsigned char)first[neg], 4))
189 {
190 ptrdiff_t len = last - first;
191 if (len < (3 + neg))
192 return nullptr;
193
194 // possible infinity or NaN, let strtod decide
195 if (first[neg] == 'i' || first[neg] == 'I')
196 {
197 // Need at most 9 chars for "-INFINITY", ignore anything after it.
198 len = std::min(len, ptrdiff_t(neg + 8));
199 }
200 else if (len > (neg + 3) && first[neg + 3] == '(')
201 {
202 // Look for end of "NAN(n-char-sequence)"
203 if (void* p = std::memchr(const_cast<char*>(first)+4, ')', len-4))
204 len = static_cast<char*>(p) + 1 - first;
205 #ifndef __cpp_exceptions
206 if (len > buffer_resource::guaranteed_capacity())
207 {
208 // The character sequence is too large for the buffer.
209 // Allocation failure could terminate the process,
210 // so just return an error via the fmt parameter.
211 fmt = chars_format{};
212 return nullptr;
213 }
214 #endif
215 }
216 else // Only need 4 chars for "-NAN"
217 len = neg + 3;
218
219 buf.assign(first, 0, len);
220 // prevent make_result correcting for "0x"
221 fmt = chars_format::general;
222 return buf.c_str();
223 }
224
225 const char* digits;
226 char* ptr;
227
228 // Assign [first,last) to a std::string to get a NTBS that can be used
229 // with strspn, strtod etc.
230 // If the string would be longer than the fixed buffer inside the
231 // buffer_resource type use find_end_of_float to try to reduce how
232 // much memory is needed, to reduce the chance of std::bad_alloc.
233
234 if (fmt == chars_format::hex)
235 {
236 digits = hex_digits;
237
238 if ((last - first + 2) > buffer_resource::guaranteed_capacity())
239 {
240 last = find_end_of_float(first + neg, last, digits, 'p');
241 #ifndef __cpp_exceptions
242 if ((last - first + 2) > buffer_resource::guaranteed_capacity())
243 {
244 // The character sequence is still too large for the buffer.
245 // Allocation failure could terminate the process,
246 // so just return an error via the fmt parameter.
247 fmt = chars_format{};
248 return nullptr;
249 }
250 #endif
251 }
252
253 buf = "-0x" + !neg;
254 buf.append(first + neg, last);
255 ptr = buf.data() + neg + 2;
256 }
257 else
258 {
259 digits = dec_digits;
260
261 if ((last - first) > buffer_resource::guaranteed_capacity())
262 {
263 last = find_end_of_float(first + neg, last, digits,
264 "e"[fmt == chars_format::fixed]);
265 #ifndef __cpp_exceptions
266 if ((last - first) > buffer_resource::guaranteed_capacity())
267 {
268 // The character sequence is still too large for the buffer.
269 // Allocation failure could terminate the process,
270 // so just return an error via the fmt parameter.
271 fmt = chars_format{};
272 return nullptr;
273 }
274 #endif
275 }
276 buf.assign(first, last);
277 ptr = buf.data() + neg;
278 }
279
280 // "A non-empty sequence of decimal digits" or
281 // "A non-empty sequence of hexadecimal digits"
282 size_t len = std::strspn(ptr, digits);
283 // "possibly containing a radix character,"
284 if (ptr[len] == '.')
285 {
286 const size_t len2 = std::strspn(ptr + len + 1, digits);
287 if (len + len2)
288 ptr += len + 1 + len2;
289 else
290 return nullptr;
291 }
292 else if (len == 0) [[unlikely]]
293 return nullptr;
294 else
295 ptr += len;
296
297 if (fmt == chars_format::fixed)
298 {
299 // Truncate the string to stop strtod parsing past this point.
300 *ptr = '\0';
301 }
302 else if (fmt == chars_format::scientific)
303 {
304 // Check for required exponent part which starts with 'e' or 'E'
305 if (*ptr != 'e' && *ptr != 'E')
306 return nullptr;
307 // then an optional plus or minus sign
308 const int sign = (ptr[1] == '-' || ptr[1] == '+');
309 // then a nonempty sequence of decimal digits
310 if (!std::memchr(dec_digits, (unsigned char)ptr[1+sign], 10))
311 return nullptr;
312 }
313 else if (fmt == chars_format::general)
314 {
315 if (*ptr == 'x' || *ptr == 'X')
316 *ptr = '\0';
317 }
318
319 return buf.c_str();
320 }
321
322 // Convert the NTBS `str` to a floating-point value of type `T`.
323 // If `str` cannot be converted, `value` is unchanged and `0` is returned.
324 // Otherwise, let N be the number of characters consumed from `str`.
325 // On success `value` is set to the converted value and N is returned.
326 // If the converted value is out of range, `value` is unchanged and
327 // -N is returned.
328 template<typename T>
329 ptrdiff_t
330 from_chars_impl(const char* str, T& value, errc& ec) noexcept
331 {
332 if (locale_t loc = ::newlocale(LC_ALL_MASK, "C", (locale_t)0)) [[likely]]
333 {
334 locale_t orig = ::uselocale(loc);
335
336 #if _GLIBCXX_USE_C99_FENV_TR1 && defined(FE_TONEAREST)
337 const int rounding = std::fegetround();
338 if (rounding != FE_TONEAREST)
339 std::fesetround(FE_TONEAREST);
340 #endif
341
342 const int save_errno = errno;
343 errno = 0;
344 char* endptr;
345 T tmpval;
346 #if _GLIBCXX_USE_C99_STDLIB
347 if constexpr (is_same_v<T, float>)
348 tmpval = std::strtof(str, &endptr);
349 else if constexpr (is_same_v<T, double>)
350 tmpval = std::strtod(str, &endptr);
351 else if constexpr (is_same_v<T, long double>)
352 tmpval = std::strtold(str, &endptr);
353 # ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
354 else if constexpr (is_same_v<T, __ieee128>)
355 tmpval = __strtoieee128(str, &endptr);
356 # endif
357 #else
358 tmpval = std::strtod(str, &endptr);
359 #endif
360 const int conv_errno = std::__exchange(errno, save_errno);
361
362 #if _GLIBCXX_USE_C99_FENV_TR1 && defined(FE_TONEAREST)
363 if (rounding != FE_TONEAREST)
364 std::fesetround(rounding);
365 #endif
366
367 ::uselocale(orig);
368 ::freelocale(loc);
369
370 const ptrdiff_t n = endptr - str;
371 if (conv_errno == ERANGE) [[unlikely]]
372 {
373 if (__builtin_isinf(tmpval)) // overflow
374 ec = errc::result_out_of_range;
375 else // underflow (LWG 3081 wants to set value = tmpval here)
376 ec = errc::result_out_of_range;
377 }
378 else if (n)
379 {
380 value = tmpval;
381 ec = errc();
382 }
383 return n;
384 }
385 else if (errno == ENOMEM)
386 ec = errc::not_enough_memory;
387
388 return 0;
389 }
390
391 inline from_chars_result
392 make_result(const char* str, ptrdiff_t n, chars_format fmt, errc ec) noexcept
393 {
394 from_chars_result result = { str, ec };
395 if (n != 0)
396 {
397 if (fmt == chars_format::hex)
398 n -= 2; // correct for the "0x" inserted into the pattern
399 result.ptr += n;
400 }
401 else if (fmt == chars_format{}) [[unlikely]]
402 {
403 // FIXME: the standard does not allow this result.
404 ec = errc::not_enough_memory;
405 }
406 return result;
407 }
408
409 #if ! _GLIBCXX_USE_CXX11_ABI
410 inline bool
411 reserve_string(std::string& s) noexcept
412 {
413 __try
414 {
415 s.reserve(buffer_resource::guaranteed_capacity());
416 }
417 __catch (const std::bad_alloc&)
418 {
419 return false;
420 }
421 return true;
422 }
423 #endif
424
425 template<typename T>
426 from_chars_result
427 from_chars_strtod(const char* first, const char* last, T& value,
428 chars_format fmt) noexcept
429 {
430 errc ec = errc::invalid_argument;
431 #if _GLIBCXX_USE_CXX11_ABI
432 buffer_resource mr;
433 pmr::string buf(&mr);
434 #else
435 string buf;
436 if (!reserve_string(buf))
437 return make_result(first, 0, {}, ec);
438 #endif
439 size_t len = 0;
440 __try
441 {
442 if (const char* pat = pattern(first, last, fmt, buf)) [[likely]]
443 len = from_chars_impl(pat, value, ec);
444 }
445 __catch (const std::bad_alloc&)
446 {
447 fmt = chars_format{};
448 }
449 return make_result(first, len, fmt, ec);
450 }
451 #endif // USE_STRTOD_FOR_FROM_CHARS
452
453 #if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
454 // Return true iff [FIRST,LAST) begins with PREFIX, ignoring case.
455 // PREFIX is assumed to not contain any uppercase letters.
456 bool
457 starts_with_ci(const char* first, const char* last, string_view prefix)
458 {
459 __glibcxx_requires_valid_range(first, last);
460
461 // A lookup table that maps uppercase letters to lowercase and
462 // is otherwise the identity mapping.
463 static constexpr auto upper_to_lower_table = [] {
464 constexpr unsigned char lower_letters[27] = "abcdefghijklmnopqrstuvwxyz";
465 constexpr unsigned char upper_letters[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
466 std::array<unsigned char, (1u << __CHAR_BIT__)> table = {};
467 for (unsigned i = 0; i < table.size(); ++i)
468 table[i] = i;
469 for (unsigned i = 0; i < 26; ++i)
470 table[upper_letters[i]] = lower_letters[i];
471 return table;
472 }();
473
474 if (last - first < static_cast<ptrdiff_t>(prefix.length()))
475 return false;
476
477 for (const unsigned char pch : prefix)
478 {
479 // __glibcxx_assert(pch == upper_to_lower_table[pch]);
480 const unsigned char ch = *first;
481 if (ch != pch && upper_to_lower_table[ch] != pch)
482 return false;
483 ++first;
484 }
485
486 return true;
487 }
488
489 // An implementation of hexadecimal float parsing for binary32/64.
490 template<typename T>
491 from_chars_result
492 __floating_from_chars_hex(const char* first, const char* last, T& value)
493 {
494 static_assert(is_same_v<T, float> || is_same_v<T, double>);
495
496 using uint_t = conditional_t<is_same_v<T, float>, uint32_t, uint64_t>;
497 constexpr int mantissa_bits = is_same_v<T, float> ? 23 : 52;
498 constexpr int exponent_bits = is_same_v<T, float> ? 8 : 11;
499 constexpr int exponent_bias = (1 << (exponent_bits - 1)) - 1;
500
501 __glibcxx_requires_valid_range(first, last);
502 if (first == last)
503 return {first, errc::invalid_argument};
504
505 // Consume the sign bit.
506 const char* const orig_first = first;
507 bool sign_bit = false;
508 if (*first == '-')
509 {
510 sign_bit = true;
511 ++first;
512 }
513
514 // Handle "inf", "infinity", "NaN" and variants thereof.
515 if (first != last)
516 if (*first == 'i' || *first == 'I' || *first == 'n' || *first == 'N') [[unlikely]]
517 {
518 if (starts_with_ci(first, last, "inf"sv))
519 {
520 first += strlen("inf");
521 if (starts_with_ci(first, last, "inity"sv))
522 first += strlen("inity");
523
524 uint_t result = 0;
525 result |= sign_bit;
526 result <<= exponent_bits;
527 result |= (1ull << exponent_bits) - 1;
528 result <<= mantissa_bits;
529 memcpy(&value, &result, sizeof(result));
530
531 return {first, errc{}};
532 }
533 else if (starts_with_ci(first, last, "nan"))
534 {
535 first += strlen("nan");
536
537 if (first != last && *first == '(')
538 {
539 // Tentatively consume the '(' as we look for an optional
540 // n-char-sequence followed by a ')'.
541 const char* const fallback_first = first;
542 for (;;)
543 {
544 ++first;
545 if (first == last)
546 {
547 first = fallback_first;
548 break;
549 }
550
551 char ch = *first;
552 if (ch == ')')
553 {
554 ++first;
555 break;
556 }
557 else if (ch == '_'
558 || __detail::__from_chars_alnum_to_val(ch) < 127)
559 continue;
560 else
561 {
562 first = fallback_first;
563 break;
564 }
565 }
566 }
567
568 // We make the implementation-defined decision of ignoring the
569 // sign bit and the n-char-sequence when assembling the NaN.
570 uint_t result = 0;
571 result <<= exponent_bits;
572 result |= (1ull << exponent_bits) - 1;
573 result <<= mantissa_bits;
574 result |= (1ull << (mantissa_bits - 1)) | 1;
575 memcpy(&value, &result, sizeof(result));
576
577 return {first, errc{}};
578 }
579 }
580
581 // Consume all insignificant leading zeros in the whole part of the
582 // mantissa.
583 bool seen_hexit = false;
584 while (first != last && *first == '0')
585 {
586 seen_hexit = true;
587 ++first;
588 }
589
590 // Now consume the rest of the written mantissa, populating MANTISSA with
591 // the first MANTISSA_BITS+k significant bits of the written mantissa, where
592 // 1 <= k <= 4 is the bit width of the leading significant written hexit.
593 //
594 // Examples:
595 // After parsing "1.2f3", MANTISSA is 0x12f30000000000 (bit_width=52+1).
596 // After parsing ".0000f0e", MANTISSA is 0xf0e00000000000 (bit_width=52+4).
597 // After parsing ".1234567890abcd8", MANTISSA is 0x1234567890abcd (bit_width=52+1)
598 // and MIDPOINT_BIT is true (and NONZERO_TAIL is false).
599 uint_t mantissa = 0;
600 int mantissa_idx = mantissa_bits; // The current bit index into MANTISSA
601 // into which we'll write the next hexit.
602 int exponent_adjustment = 0; // How much we'd have to adjust the written
603 // exponent in order to represent the mantissa
604 // in scientific form h.hhhhhhhhhhhhh.
605 bool midpoint_bit = false; // Whether the MANTISSA_BITS+k+1 significant
606 // bit is set in the written mantissa.
607 bool nonzero_tail = false; // Whether some bit thereafter is set in the
608 // written mantissa.
609 bool seen_decimal_point = false;
610 for (; first != last; ++first)
611 {
612 char ch = *first;
613 if (ch == '.' && !seen_decimal_point)
614 {
615 seen_decimal_point = true;
616 continue;
617 }
618
619 int hexit = __detail::__from_chars_alnum_to_val(ch);
620 if (hexit >= 16)
621 break;
622 seen_hexit = true;
623
624 if (!seen_decimal_point && mantissa != 0)
625 exponent_adjustment += 4;
626 else if (seen_decimal_point && mantissa == 0)
627 {
628 exponent_adjustment -= 4;
629 if (hexit == 0x0)
630 continue;
631 }
632
633 if (mantissa_idx >= 0)
634 mantissa |= uint_t(hexit) << mantissa_idx;
635 else if (mantissa_idx >= -4)
636 {
637 if constexpr (is_same_v<T, float>)
638 {
639 __glibcxx_assert(mantissa_idx == -1);
640 mantissa |= hexit >> 1;
641 midpoint_bit = (hexit & 0b0001) != 0;
642 }
643 else
644 {
645 __glibcxx_assert(mantissa_idx == -4);
646 midpoint_bit = (hexit & 0b1000) != 0;
647 nonzero_tail = (hexit & 0b0111) != 0;
648 }
649 }
650 else
651 nonzero_tail |= (hexit != 0x0);
652
653 mantissa_idx -= 4;
654 }
655 if (mantissa != 0)
656 __glibcxx_assert(__bit_width(mantissa) >= mantissa_bits + 1
657 && __bit_width(mantissa) <= mantissa_bits + 4);
658 else
659 __glibcxx_assert(!midpoint_bit && !nonzero_tail);
660
661 if (!seen_hexit)
662 // If we haven't seen any hexit at this point, the parse failed.
663 return {orig_first, errc::invalid_argument};
664
665 // Parse the written exponent.
666 int written_exponent = 0;
667 if (first != last && (*first == 'p' || *first == 'P'))
668 {
669 // Tentatively consume the 'p' and try to parse a decimal number.
670 const char* const fallback_first = first;
671 ++first;
672 if (first != last && *first == '+')
673 ++first;
674 from_chars_result fcr = from_chars(first, last, written_exponent, 10);
675 if (fcr.ptr == first)
676 // The parse failed, so undo consuming the 'p' and carry on as if the
677 // exponent was omitted (i.e. is 0).
678 first = fallback_first;
679 else
680 {
681 first = fcr.ptr;
682 if (mantissa != 0 && fcr.ec == errc::result_out_of_range)
683 // Punt on very large exponents for now. FIXME
684 return {first, errc::result_out_of_range};
685 }
686 }
687 int biased_exponent = written_exponent + exponent_bias;
688 if (exponent_adjustment != 0)
689 // The mantissa wasn't written in scientific form. Adjust the exponent
690 // so that we may assume scientific form.
691 //
692 // Examples;
693 // For input "a.bcp5", EXPONENT_ADJUSTMENT would be 0 since this
694 // written mantissa is already in scientific form.
695 // For input "ab.cp5", EXPONENT_ADJUSTMENT would be 4 since the
696 // scientific form is "a.bcp9".
697 // For input 0.0abcp5", EXPONENT_ADJUSTMENT would be -8 since the
698 // scientific form is "a.bcp-3".
699 biased_exponent += exponent_adjustment;
700
701 // Shifts the mantissa to the right by AMOUNT while updating
702 // BIASED_EXPONENT, MIDPOINT_BIT and NONZERO_TAIL accordingly.
703 auto shift_mantissa = [&] (int amount) {
704 __glibcxx_assert(amount >= 0);
705 if (amount > mantissa_bits + 1)
706 {
707 // Shifting the mantissa by an amount greater than its precision.
708 nonzero_tail |= midpoint_bit;
709 nonzero_tail |= mantissa != 0;
710 midpoint_bit = false;
711 mantissa = 0;
712 biased_exponent += amount;
713 }
714 else if (amount != 0)
715 {
716 nonzero_tail |= midpoint_bit;
717 nonzero_tail |= (mantissa & ((1ull << (amount - 1)) - 1)) != 0;
718 midpoint_bit = (mantissa & (1ull << (amount - 1))) != 0;
719 mantissa >>= amount;
720 biased_exponent += amount;
721 }
722 };
723
724 if (mantissa != 0)
725 {
726 // If the leading hexit is not '1', shift MANTISSA to make it so.
727 // This normalizes input like "4.08p0" into "1.02p2".
728 const int leading_hexit = mantissa >> mantissa_bits;
729 const int leading_hexit_width = __bit_width(leading_hexit); // FIXME: optimize?
730 __glibcxx_assert(leading_hexit_width >= 1 && leading_hexit_width <= 4);
731 shift_mantissa(leading_hexit_width - 1);
732 // After this adjustment, we can assume the leading hexit is '1'.
733 __glibcxx_assert((mantissa >> mantissa_bits) == 0x1);
734 }
735
736 if (biased_exponent <= 0)
737 {
738 // This number is too small to be represented as a normal number, so
739 // try for a subnormal number by shifting the mantissa sufficiently.
740 // We need to shift by 1 more than -BIASED_EXPONENT because the leading
741 // mantissa bit is omitted in the representation of a normal number but
742 // not in a subnormal number.
743 shift_mantissa(-biased_exponent + 1);
744 __glibcxx_assert(!(mantissa & (1ull << mantissa_bits)));
745 __glibcxx_assert(biased_exponent == 1);
746 biased_exponent = 0;
747 }
748
749 // Perform round-to-nearest, tie-to-even rounding according to
750 // MIDPOINT_BIT and NONZERO_TAIL.
751 if (midpoint_bit && (nonzero_tail || (mantissa % 2) != 0))
752 {
753 // Rounding away from zero.
754 ++mantissa;
755 midpoint_bit = false;
756 nonzero_tail = false;
757
758 // Deal with a couple of corner cases after rounding.
759 if (mantissa == (1ull << mantissa_bits))
760 {
761 // We rounded the subnormal number 1.fffffffffffff...p-1023
762 // up to the normal number 1p-1022.
763 __glibcxx_assert(biased_exponent == 0);
764 ++biased_exponent;
765 }
766 else if (mantissa & (1ull << (mantissa_bits + 1)))
767 {
768 // We rounded the normal number 1.fffffffffffff8pN (with maximal
769 // mantissa) up to to 1p(N+1).
770 mantissa >>= 1;
771 ++biased_exponent;
772 }
773 }
774 else
775 {
776 // Rounding toward zero.
777
778 if (mantissa == 0 && (midpoint_bit || nonzero_tail))
779 {
780 // A nonzero number that rounds to zero is unrepresentable.
781 __glibcxx_assert(biased_exponent == 0);
782 return {first, errc::result_out_of_range};
783 }
784
785 midpoint_bit = false;
786 nonzero_tail = false;
787 }
788
789 if (mantissa != 0 && biased_exponent >= (1 << exponent_bits) - 1)
790 // The exponent of this number is too large to be representable.
791 return {first, errc::result_out_of_range};
792
793 uint_t result = 0;
794 if (mantissa == 0)
795 {
796 // Assemble a (possibly signed) zero.
797 if (sign_bit)
798 result |= 1ull << (exponent_bits + mantissa_bits);
799 }
800 else
801 {
802 // Assemble a nonzero normal or subnormal value.
803 result |= sign_bit;
804 result <<= exponent_bits;
805 result |= biased_exponent;
806 result <<= mantissa_bits;
807 result |= mantissa & ((1ull << mantissa_bits) - 1);
808 // The implicit leading mantissa bit is set iff the number is normal.
809 __glibcxx_assert(((mantissa & (1ull << mantissa_bits)) != 0)
810 == (biased_exponent != 0));
811 }
812 memcpy(&value, &result, sizeof(result));
813
814 return {first, errc{}};
815 }
816 #endif // _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
817
818 } // namespace
819
820 #if USE_LIB_FAST_FLOAT || USE_STRTOD_FOR_FROM_CHARS
821
822 from_chars_result
823 from_chars(const char* first, const char* last, float& value,
824 chars_format fmt) noexcept
825 {
826 #if USE_LIB_FAST_FLOAT
827 if (fmt == chars_format::hex)
828 return __floating_from_chars_hex(first, last, value);
829 else
830 {
831 return fast_float::from_chars(first, last, value, fmt);
832 }
833 #else
834 return from_chars_strtod(first, last, value, fmt);
835 #endif
836 }
837
838 from_chars_result
839 from_chars(const char* first, const char* last, double& value,
840 chars_format fmt) noexcept
841 {
842 #if USE_LIB_FAST_FLOAT
843 if (fmt == chars_format::hex)
844 return __floating_from_chars_hex(first, last, value);
845 else
846 {
847 return fast_float::from_chars(first, last, value, fmt);
848 }
849 #else
850 return from_chars_strtod(first, last, value, fmt);
851 #endif
852 }
853
854 from_chars_result
855 from_chars(const char* first, const char* last, long double& value,
856 chars_format fmt) noexcept
857 {
858 #if ! USE_STRTOD_FOR_FROM_CHARS
859 // Either long double is the same as double, or we can't use strtold.
860 // In the latter case, this might give an incorrect result (e.g. values
861 // out of range of double give an error, even if they fit in long double).
862 double dbl_value;
863 from_chars_result result;
864 if (fmt == chars_format::hex)
865 result = __floating_from_chars_hex(first, last, dbl_value);
866 else
867 {
868 result = fast_float::from_chars(first, last, dbl_value, fmt);
869 }
870 if (result.ec == errc{})
871 value = dbl_value;
872 return result;
873 #else
874 return from_chars_strtod(first, last, value, fmt);
875 #endif
876 }
877
878 #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
879 // Make std::from_chars for 64-bit long double an alias for the overload
880 // for double.
881 extern "C" from_chars_result
882 _ZSt10from_charsPKcS0_ReSt12chars_format(const char* first, const char* last,
883 long double& value,
884 chars_format fmt) noexcept
885 __attribute__((alias ("_ZSt10from_charsPKcS0_RdSt12chars_format")));
886 #endif
887
888 #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
889 from_chars_result
890 from_chars(const char* first, const char* last, __ieee128& value,
891 chars_format fmt) noexcept
892 {
893 // fast_float doesn't support IEEE binary128 format, but we can use strtold.
894 return from_chars_strtod(first, last, value, fmt);
895 }
896 #endif
897
898 #endif // USE_LIB_FAST_FLOAT || USE_STRTOD_FOR_FROM_CHARS
899
900 _GLIBCXX_END_NAMESPACE_VERSION
901 } // namespace std
This page took 0.086269 seconds and 5 git commands to generate.