123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- #ifndef BOOST_CHARCONV_DETAIL_COMPUTE_FLOAT80_HPP
- #define BOOST_CHARCONV_DETAIL_COMPUTE_FLOAT80_HPP
- #include <boost/charconv/detail/config.hpp>
- #include <boost/charconv/detail/emulated128.hpp>
- #include <boost/charconv/detail/bit_layouts.hpp>
- #include <system_error>
- #include <type_traits>
- #include <limits>
- #include <cstdint>
- #include <cmath>
- #include <climits>
- #include <cfloat>
- #ifdef BOOST_CHARCONV_DEBUG_FLOAT128
- #include <iostream>
- #include <iomanip>
- #include <boost/charconv/detail/to_chars_integer_impl.hpp>
- #endif
- namespace boost { namespace charconv { namespace detail {
- #if BOOST_CHARCONV_LDBL_BITS > 64
- static constexpr long double powers_of_ten_ld[] = {
- 1e0L, 1e1L, 1e2L, 1e3L, 1e4L, 1e5L, 1e6L,
- 1e7L, 1e8L, 1e9L, 1e10L, 1e11L, 1e12L, 1e13L,
- 1e14L, 1e15L, 1e16L, 1e17L, 1e18L, 1e19L, 1e20L,
- 1e21L, 1e22L, 1e23L, 1e24L, 1e25L, 1e26L, 1e27L,
- 1e28L, 1e29L, 1e30L, 1e31L, 1e32L, 1e33L, 1e34L,
- 1e35L, 1e36L, 1e37L, 1e38L, 1e39L, 1e40L, 1e41L,
- 1e42L, 1e43L, 1e44L, 1e45L, 1e46L, 1e47L, 1e48L,
- 1e49L, 1e50L, 1e51L, 1e52L, 1e53L, 1e54L, 1e55L
- };
- template <typename ResultType, typename Unsigned_Integer, typename ArrayPtr>
- inline ResultType fast_path(std::int64_t q, Unsigned_Integer w, bool negative, ArrayPtr table) noexcept
- {
-
-
-
-
-
- auto ld = static_cast<ResultType>(w);
- if (q < 0)
- {
- ld /= table[-q];
- }
- else
- {
- ld *= table[q];
- }
- if (negative)
- {
- ld = -ld;
- }
- return ld;
- }
- template <typename ResultType, typename Unsigned_Integer>
- inline ResultType compute_float80(std::int64_t q, Unsigned_Integer w, bool negative, std::errc& success) noexcept
- {
-
-
- static constexpr auto smallest_power = -4951 - 39;
- static constexpr auto largest_power = 4932;
-
-
-
-
-
- static constexpr auto clinger_max_exp = BOOST_CHARCONV_LDBL_BITS == 80 ? 27 : 48;
- static constexpr auto clinger_min_exp = BOOST_CHARCONV_LDBL_BITS == 80 ? -34 : -55;
- if (clinger_min_exp <= q && q <= clinger_max_exp && w <= static_cast<Unsigned_Integer>(1) << 113)
- {
- success = std::errc();
- return fast_path<ResultType>(q, w, negative, powers_of_ten_ld);
- }
- if (w == 0)
- {
- success = std::errc();
- return negative ? -0.0L : 0.0L;
- }
- else if (q > largest_power)
- {
- success = std::errc::result_out_of_range;
- return negative ? -HUGE_VALL : HUGE_VALL;
- }
- else if (q < smallest_power)
- {
- success = std::errc::result_out_of_range;
- return negative ? -0.0L : 0.0L;
- }
- success = std::errc::not_supported;
- return 0;
- }
- #endif
- }}}
- #endif
|