File indexing completed on 2025-04-19 08:19:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #ifndef BOOST_CHARCONV_DETAIL_DRAGONBOX_HPP
0023 #define BOOST_CHARCONV_DETAIL_DRAGONBOX_HPP
0024
0025 #include <boost/charconv/detail/config.hpp>
0026 #include <boost/charconv/detail/dragonbox/dragonbox_common.hpp>
0027 #include <boost/charconv/detail/bit_layouts.hpp>
0028 #include <boost/charconv/detail/emulated128.hpp>
0029 #include <boost/charconv/detail/buffer_sizing.hpp>
0030 #include <boost/charconv/detail/to_chars_result.hpp>
0031 #include <boost/charconv/chars_format.hpp>
0032 #include <boost/core/bit.hpp>
0033 #include <type_traits>
0034 #include <limits>
0035 #include <cstdint>
0036 #include <cstring>
0037
0038 #ifdef BOOST_MSVC
0039 # pragma warning(push)
0040 # pragma warning(disable: 4127)
0041 # pragma warning(disable: 4307)
0042 #endif
0043
0044 namespace boost { namespace charconv { namespace detail {
0045
0046
0047
0048
0049
0050
0051
0052 template <typename T>
0053 struct dragonbox_float_traits
0054 {
0055
0056
0057 static_assert(std::numeric_limits<T>::is_iec559 && std::numeric_limits<T>::radix == 2 &&
0058 (physical_bits<T>::value == 32 || physical_bits<T>::value == 64),
0059 "default_ieee754_traits only works for 32-bits or 64-bits types "
0060 "supporting binary32 or binary64 formats!");
0061
0062
0063 using type = T;
0064
0065
0066 using format = typename std::conditional<physical_bits<T>::value == 32, ieee754_binary32, ieee754_binary64>::type;
0067
0068
0069
0070 using carrier_uint =
0071 typename std::conditional<physical_bits<T>::value == 32, std::uint32_t, std::uint64_t>::type;
0072
0073 static_assert(sizeof(carrier_uint) == sizeof(T), "Type T must have a unsigned type with the same number of bits");
0074
0075
0076 static constexpr int carrier_bits = static_cast<int>(physical_bits<carrier_uint>::value);
0077
0078
0079
0080
0081
0082 static T carrier_to_float(carrier_uint u) noexcept
0083 {
0084 T x;
0085 std::memcpy(&x, &u, sizeof(carrier_uint));
0086 return x;
0087 }
0088
0089
0090 static carrier_uint float_to_carrier(T x) noexcept
0091 {
0092 carrier_uint u;
0093 std::memcpy(&u, &x, sizeof(carrier_uint));
0094 return u;
0095 }
0096
0097
0098
0099
0100 static constexpr unsigned extract_exponent_bits(carrier_uint u) noexcept
0101 {
0102 return static_cast<unsigned>(u >> format::significand_bits) & ((static_cast<unsigned int>(1) << format::exponent_bits) - 1);
0103 }
0104
0105
0106
0107
0108 static constexpr carrier_uint extract_significand_bits(carrier_uint u) noexcept
0109 {
0110 return carrier_uint(u & carrier_uint((carrier_uint(1) << format::significand_bits) - 1));
0111 }
0112
0113
0114 static constexpr carrier_uint remove_exponent_bits(carrier_uint u, unsigned int exponent_bits) noexcept
0115 {
0116 return u ^ (carrier_uint(exponent_bits) << format::significand_bits);
0117 }
0118
0119
0120 static constexpr carrier_uint remove_sign_bit_and_shift(carrier_uint u) noexcept {
0121 return carrier_uint(carrier_uint(u) << 1);
0122 }
0123
0124
0125
0126 static constexpr int exponent_bias = 1 - (1 << (carrier_bits - format::significand_bits - 2));
0127
0128
0129 static constexpr int binary_exponent(unsigned exponent_bits) noexcept
0130 {
0131 return static_cast<int>(exponent_bits == 0 ? format::min_exponent : int(exponent_bits) + format::exponent_bias);
0132 }
0133
0134
0135
0136 static constexpr carrier_uint binary_significand(carrier_uint significand_bits, unsigned exponent_bits) noexcept
0137 {
0138 return exponent_bits == 0 ? significand_bits : significand_bits | (carrier_uint(1) << format::significand_bits);
0139 }
0140
0141
0142
0143 static constexpr bool is_nonzero(carrier_uint u) noexcept
0144 {
0145 return (u << 1) != 0;
0146 }
0147
0148 static constexpr bool is_positive(carrier_uint u) noexcept
0149 {
0150 return u < (carrier_uint(1) << (format::significand_bits + format::exponent_bits));
0151 }
0152
0153 static constexpr bool is_negative(carrier_uint u) noexcept
0154 {
0155 return !is_positive(u);
0156 }
0157
0158 static constexpr bool is_finite(unsigned exponent_bits) noexcept
0159 {
0160 return exponent_bits != ((1u << format::exponent_bits) - 1);
0161 }
0162
0163 static constexpr bool has_all_zero_significand_bits(carrier_uint u) noexcept
0164 {
0165 return (u << 1) == 0;
0166 }
0167
0168 static constexpr bool has_even_significand_bits(carrier_uint u) noexcept
0169 {
0170 return u % 2 == 0;
0171 }
0172 };
0173
0174
0175
0176
0177
0178
0179 template <typename T, typename Traits = dragonbox_float_traits<T>>
0180 struct dragonbox_float_bits;
0181
0182 template <typename T, typename Traits = dragonbox_float_traits<T>>
0183 struct dragonbox_signed_significand_bits;
0184
0185 template <typename T, typename Traits>
0186 struct dragonbox_float_bits
0187 {
0188 using type = T;
0189 using traits_type = Traits;
0190 using carrier_uint = typename traits_type::carrier_uint;
0191
0192 carrier_uint u;
0193
0194 dragonbox_float_bits() = default;
0195 constexpr explicit dragonbox_float_bits(carrier_uint bit_pattern) noexcept : u{bit_pattern} {}
0196 constexpr explicit dragonbox_float_bits(T float_value) noexcept
0197 : u{traits_type::float_to_carrier(float_value)} {}
0198
0199 T to_float() const noexcept
0200 {
0201 return traits_type::carrier_to_float(u);
0202 }
0203
0204
0205
0206
0207 constexpr unsigned int extract_exponent_bits() const noexcept
0208 {
0209 return traits_type::extract_exponent_bits(u);
0210 }
0211
0212
0213
0214
0215 constexpr carrier_uint extract_significand_bits() const noexcept
0216 {
0217 return traits_type::extract_significand_bits(u);
0218 }
0219
0220
0221 constexpr auto remove_exponent_bits(unsigned int exponent_bits) const noexcept -> dragonbox_signed_significand_bits<type, traits_type>
0222 {
0223 return dragonbox_signed_significand_bits<type, traits_type>(traits_type::remove_exponent_bits(u, exponent_bits));
0224 }
0225
0226
0227 static constexpr int binary_exponent(unsigned exponent_bits) noexcept
0228 {
0229 return traits_type::binary_exponent(exponent_bits);
0230 }
0231
0232 constexpr int binary_exponent() const noexcept
0233 {
0234 return binary_exponent(extract_exponent_bits());
0235 }
0236
0237
0238
0239 static constexpr carrier_uint binary_significand(carrier_uint significand_bits, unsigned exponent_bits) noexcept
0240 {
0241 return traits_type::binary_significand(significand_bits, exponent_bits);
0242 }
0243
0244 constexpr carrier_uint binary_significand() const noexcept
0245 {
0246 return binary_significand(extract_significand_bits(), extract_exponent_bits());
0247 }
0248
0249 constexpr bool is_nonzero() const noexcept
0250 {
0251 return traits_type::is_nonzero(u);
0252 }
0253
0254 constexpr bool is_positive() const noexcept
0255 {
0256 return traits_type::is_positive(u);
0257 }
0258
0259 constexpr bool is_negative() const noexcept
0260 {
0261 return traits_type::is_negative(u);
0262 }
0263
0264 constexpr bool is_finite(unsigned exponent_bits) const noexcept
0265 {
0266 return traits_type::is_finite(exponent_bits);
0267 }
0268
0269 constexpr bool is_finite() const noexcept
0270 {
0271 return traits_type::is_finite(extract_exponent_bits());
0272 }
0273
0274 constexpr bool has_even_significand_bits() const noexcept
0275 {
0276 return traits_type::has_even_significand_bits(u);
0277 }
0278 };
0279
0280 template <typename T, typename Traits>
0281 struct dragonbox_signed_significand_bits
0282 {
0283 using type = T;
0284 using traits_type = Traits;
0285 using carrier_uint = typename traits_type::carrier_uint;
0286
0287 carrier_uint u;
0288
0289 dragonbox_signed_significand_bits() = default;
0290 constexpr explicit dragonbox_signed_significand_bits(carrier_uint bit_pattern) noexcept
0291 : u{bit_pattern} {}
0292
0293
0294 constexpr carrier_uint remove_sign_bit_and_shift() const noexcept
0295 {
0296 return traits_type::remove_sign_bit_and_shift(u);
0297 }
0298
0299 constexpr bool is_positive() const noexcept
0300 {
0301 return traits_type::is_positive(u);
0302 }
0303
0304 constexpr bool is_negative() const noexcept
0305 {
0306 return traits_type::is_negative(u);
0307 }
0308
0309 constexpr bool has_all_zero_significand_bits() const noexcept
0310 {
0311 return traits_type::has_all_zero_significand_bits(u);
0312 }
0313
0314 constexpr bool has_even_significand_bits() const noexcept
0315 {
0316 return traits_type::has_even_significand_bits(u);
0317 }
0318 };
0319
0320
0321
0322
0323
0324 namespace div {
0325
0326
0327
0328
0329 template <int N>
0330 struct divide_by_pow10_info;
0331
0332 template <>
0333 struct divide_by_pow10_info<1>
0334 {
0335 static constexpr std::uint32_t magic_number = 6554;
0336 static constexpr int shift_amount = 16;
0337 };
0338
0339 template <>
0340 struct divide_by_pow10_info<2>
0341 {
0342 static constexpr std::uint32_t magic_number = 656;
0343 static constexpr int shift_amount = 16;
0344 };
0345
0346 template <int N>
0347 BOOST_CXX14_CONSTEXPR bool check_divisibility_and_divide_by_pow10(std::uint32_t& n) noexcept
0348 {
0349
0350
0351 BOOST_CHARCONV_ASSERT(n <= compute_power(UINT32_C(10), N + 1));
0352
0353 using info = divide_by_pow10_info<N>;
0354 n *= info::magic_number;
0355
0356 constexpr auto mask = std::uint32_t(std::uint32_t(1) << info::shift_amount) - 1;
0357 bool result = ((n & mask) < info::magic_number);
0358
0359 n >>= info::shift_amount;
0360 return result;
0361 }
0362
0363
0364
0365 template <int N>
0366 BOOST_CXX14_CONSTEXPR std::uint32_t small_division_by_pow10(std::uint32_t n) noexcept
0367 {
0368
0369
0370 BOOST_CHARCONV_ASSERT(n <= compute_power(UINT32_C(10), N + 1));
0371
0372 return (n * divide_by_pow10_info<N>::magic_number) >> divide_by_pow10_info<N>::shift_amount;
0373 }
0374
0375
0376
0377 template <unsigned N, typename UInt, UInt n_max>
0378 BOOST_CXX14_CONSTEXPR UInt divide_by_pow10(UInt n) noexcept
0379 {
0380
0381
0382
0383
0384
0385
0386 BOOST_IF_CONSTEXPR (std::is_same<UInt, std::uint32_t>::value && N == 2)
0387 {
0388 return static_cast<UInt>(umul64(static_cast<std::uint32_t>(n), UINT32_C(1374389535)) >> 37);
0389 }
0390
0391
0392 else BOOST_IF_CONSTEXPR (std::is_same<UInt, std::uint64_t>::value && N == 3 && n_max <= UINT64_C(15534100272597517998))
0393 {
0394 return static_cast<UInt>(umul128_upper64(n, UINT64_C(2361183241434822607)) >> 7);
0395 }
0396 else
0397 {
0398 BOOST_CXX14_CONSTEXPR auto divisor = compute_power(static_cast<UInt>(10), N);
0399 return n / divisor;
0400 }
0401 }
0402
0403 #ifdef BOOST_MSVC
0404 # pragma warning(push)
0405 # pragma warning(disable: 4100)
0406 #endif
0407
0408 template <typename UInt>
0409 BOOST_CXX14_CONSTEXPR UInt divide_by_pow10(unsigned N, BOOST_ATTRIBUTE_UNUSED UInt n_max, UInt n) noexcept
0410 {
0411 BOOST_IF_CONSTEXPR (std::is_same<UInt, std::uint32_t>::value && N == 2)
0412 {
0413 return static_cast<UInt>(umul64(static_cast<std::uint32_t>(n), static_cast<std::uint32_t>(1374389535)) >> UINT32_C(37));
0414 }
0415
0416
0417 else BOOST_IF_CONSTEXPR (std::is_same<UInt, std::uint64_t>::value && N == 3 && n_max <= UINT64_C(15534100272597517998))
0418 {
0419 return static_cast<UInt>(umul128_upper64(n, UINT64_C(2361183241434822607)) >> 7);
0420 }
0421 else
0422 {
0423 auto divisor = compute_power(static_cast<UInt>(10), N);
0424 return n / divisor;
0425 }
0426 }
0427
0428 #ifdef BOOST_MSVC
0429 # pragma warning(pop)
0430 #endif
0431 }
0432
0433
0434
0435
0436
0437 template <typename UInt, bool is_signed, bool trailing_zero_flag>
0438 struct decimal_fp;
0439
0440 template <typename UInt>
0441 struct decimal_fp<UInt, false, false>
0442 {
0443 using carrier_uint = UInt;
0444
0445 carrier_uint significand;
0446 int exponent;
0447 };
0448
0449 template <typename UInt>
0450 struct decimal_fp<UInt, true, false>
0451 {
0452 using carrier_uint = UInt;
0453
0454 carrier_uint significand;
0455 int exponent;
0456 bool is_negative;
0457 };
0458
0459 template <typename UInt>
0460 struct decimal_fp<UInt, false, true>
0461 {
0462 using carrier_uint = UInt;
0463
0464 carrier_uint significand;
0465 int exponent;
0466 bool may_have_trailing_zeros;
0467 };
0468
0469 template <typename UInt>
0470 struct decimal_fp<UInt, true, true>
0471 {
0472 using carrier_uint = UInt;
0473
0474 carrier_uint significand;
0475 int exponent;
0476 bool is_negative;
0477 bool may_have_trailing_zeros;
0478 };
0479
0480 template <typename UInt>
0481 using unsigned_decimal_fp = decimal_fp<UInt, false, false>;
0482
0483 template <typename UInt>
0484 using signed_decimal_fp = decimal_fp<UInt, true, false>;
0485
0486
0487
0488
0489
0490 #if (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
0491 template <bool b>
0492 struct cache_holder_ieee754_binary32_impl
0493 #else
0494 struct cache_holder_ieee754_binary32
0495 #endif
0496 {
0497 using cache_entry_type = std::uint64_t;
0498 static constexpr int cache_bits = 64;
0499 static constexpr int min_k = -31;
0500 static constexpr int max_k = 46;
0501 static constexpr cache_entry_type cache[] = {
0502 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f, 0xfd87b5f28300ca0e,
0503 0x9e74d1b791e07e49, 0xc612062576589ddb, 0xf79687aed3eec552, 0x9abe14cd44753b53,
0504 0xc16d9a0095928a28, 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb,
0505 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a, 0xe69594bec44de15c,
0506 0x901d7cf73ab0acda, 0xb424dc35095cd810, 0xe12e13424bb40e14, 0x8cbccc096f5088cc,
0507 0xafebff0bcb24aaff, 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd,
0508 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424, 0xd1b71758e219652c,
0509 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b, 0xcccccccccccccccd, 0x8000000000000000,
0510 0xa000000000000000, 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000,
0511 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, 0xbebc200000000000,
0512 0xee6b280000000000, 0x9502f90000000000, 0xba43b74000000000, 0xe8d4a51000000000,
0513 0x9184e72a00000000, 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000,
0514 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, 0xad78ebc5ac620000,
0515 0xd8d726b7177a8000, 0x878678326eac9000, 0xa968163f0a57b400, 0xd3c21bcecceda100,
0516 0x84595161401484a0, 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940985,
0517 0xa18f07d736b90be6, 0xc9f2c9cd04674edf, 0xfc6f7c4045812297, 0x9dc5ada82b70b59e,
0518 0xc5371912364ce306, 0xf684df56c3e01bc7, 0x9a130b963a6c115d, 0xc097ce7bc90715b4,
0519 0xf0bdc21abb48db21, 0x96769950b50d88f5, 0xbc143fa4e250eb32, 0xeb194f8e1ae525fe,
0520 0x92efd1b8d0cf37bf, 0xb7abc627050305ae, 0xe596b7b0c643c71a, 0x8f7e32ce7bea5c70,
0521 0xb35dbf821ae4f38c, 0xe0352f62a19e306f};
0522 };
0523
0524 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
0525
0526 template <bool b> constexpr int cache_holder_ieee754_binary32_impl<b>::cache_bits;
0527 template <bool b> constexpr int cache_holder_ieee754_binary32_impl<b>::min_k;
0528 template <bool b> constexpr int cache_holder_ieee754_binary32_impl<b>::max_k;
0529 template <bool b> constexpr typename cache_holder_ieee754_binary32_impl<b>::cache_entry_type cache_holder_ieee754_binary32_impl<b>::cache[];
0530
0531 #endif
0532
0533 #if (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
0534 using cache_holder_ieee754_binary32 = cache_holder_ieee754_binary32_impl<true>;
0535 #endif
0536
0537 #if (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
0538 template <bool b>
0539 struct cache_holder_ieee754_binary64_impl
0540 #else
0541 struct cache_holder_ieee754_binary64
0542 #endif
0543 {
0544 using cache_entry_type = uint128;
0545 static constexpr int cache_bits = 128;
0546 static constexpr int min_k = -292;
0547 static constexpr int max_k = 326;
0548 static constexpr cache_entry_type cache[] = {
0549 {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, {0x9faacf3df73609b1, 0x77b191618c54e9ad},
0550 {0xc795830d75038c1d, 0xd59df5b9ef6a2418}, {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e},
0551 {0x9becce62836ac577, 0x4ee367f9430aec33}, {0xc2e801fb244576d5, 0x229c41f793cda740},
0552 {0xf3a20279ed56d48a, 0x6b43527578c11110}, {0x9845418c345644d6, 0x830a13896b78aaaa},
0553 {0xbe5691ef416bd60c, 0x23cc986bc656d554}, {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9},
0554 {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa}, {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54},
0555 {0xe858ad248f5c22c9, 0xd1b3400f8f9cff69}, {0x91376c36d99995be, 0x23100809b9c21fa2},
0556 {0xb58547448ffffb2d, 0xabd40a0c2832a78b}, {0xe2e69915b3fff9f9, 0x16c90c8f323f516d},
0557 {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4}, {0xb1442798f49ffb4a, 0x99cd11cfdf41779d},
0558 {0xdd95317f31c7fa1d, 0x40405643d711d584}, {0x8a7d3eef7f1cfc52, 0x482835ea666b2573},
0559 {0xad1c8eab5ee43b66, 0xda3243650005eed0}, {0xd863b256369d4a40, 0x90bed43e40076a83},
0560 {0x873e4f75e2224e68, 0x5a7744a6e804a292}, {0xa90de3535aaae202, 0x711515d0a205cb37},
0561 {0xd3515c2831559a83, 0x0d5a5b44ca873e04}, {0x8412d9991ed58091, 0xe858790afe9486c3},
0562 {0xa5178fff668ae0b6, 0x626e974dbe39a873}, {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},
0563 {0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a}, {0xa139029f6a239f72, 0x1c1fffc1ebc44e81},
0564 {0xc987434744ac874e, 0xa327ffb266b56221}, {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9},
0565 {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa}, {0xc4ce17b399107c22, 0xcb550fb4384d21d4},
0566 {0xf6019da07f549b2b, 0x7e2a53a146606a49}, {0x99c102844f94e0fb, 0x2eda7444cbfc426e},
0567 {0xc0314325637a1939, 0xfa911155fefb5309}, {0xf03d93eebc589f88, 0x793555ab7eba27cb},
0568 {0x96267c7535b763b5, 0x4bc1558b2f3458df}, {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17},
0569 {0xea9c227723ee8bcb, 0x465e15a979c1cadd}, {0x92a1958a7675175f, 0x0bfacd89ec191eca},
0570 {0xb749faed14125d36, 0xcef980ec671f667c}, {0xe51c79a85916f484, 0x82b7e12780e7401b},
0571 {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811}, {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16},
0572 {0xdfbdcece67006ac9, 0x67a791e093e1d49b}, {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1},
0573 {0xaecc49914078536d, 0x58fae9f773886e19}, {0xda7f5bf590966848, 0xaf39a475506a899f},
0574 {0x888f99797a5e012d, 0x6d8406c952429604}, {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84},
0575 {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65}, {0x855c3be0a17fcd26, 0x5cf2eea09a550680},
0576 {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, {0xd0601d8efc57b08b, 0xf13b94daf124da27},
0577 {0x823c12795db6ce57, 0x76c53d08d6b70859}, {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f},
0578 {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a}, {0xfe5d54150b090b02, 0xd3f93b35435d7c4d},
0579 {0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0}, {0xc6b8e9b0709f109a, 0x359ab6419ca1091c},
0580 {0xf867241c8cc6d4c0, 0xc30163d203c94b63}, {0x9b407691d7fc44f8, 0x79e0de63425dcf1e},
0581 {0xc21094364dfb5636, 0x985915fc12f542e5}, {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e},
0582 {0x979cf3ca6cec5b5a, 0xa705992ceecf9c43}, {0xbd8430bd08277231, 0x50c6ff782a838354},
0583 {0xece53cec4a314ebd, 0xa4f8bf5635246429}, {0x940f4613ae5ed136, 0x871b7795e136be9a},
0584 {0xb913179899f68584, 0x28e2557b59846e40}, {0xe757dd7ec07426e5, 0x331aeada2fe589d0},
0585 {0x9096ea6f3848984f, 0x3ff0d2c85def7622}, {0xb4bca50b065abe63, 0x0fed077a756b53aa},
0586 {0xe1ebce4dc7f16dfb, 0xd3e8495912c62895}, {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d},
0587 {0xb080392cc4349dec, 0xbd8d794d96aacfb4}, {0xdca04777f541c567, 0xecf0d7a0fc5583a1},
0588 {0x89e42caaf9491b60, 0xf41686c49db57245}, {0xac5d37d5b79b6239, 0x311c2875c522ced6},
0589 {0xd77485cb25823ac7, 0x7d633293366b828c}, {0x86a8d39ef77164bc, 0xae5dff9c02033198},
0590 {0xa8530886b54dbdeb, 0xd9f57f830283fdfd}, {0xd267caa862a12d66, 0xd072df63c324fd7c},
0591 {0x8380dea93da4bc60, 0x4247cb9e59f71e6e}, {0xa46116538d0deb78, 0x52d9be85f074e609},
0592 {0xcd795be870516656, 0x67902e276c921f8c}, {0x806bd9714632dff6, 0x00ba1cd8a3db53b7},
0593 {0xa086cfcd97bf97f3, 0x80e8a40eccd228a5}, {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce},
0594 {0xfad2a4b13d1b5d6c, 0x796b805720085f82}, {0x9cc3a6eec6311a63, 0xcbe3303674053bb1},
0595 {0xc3f490aa77bd60fc, 0xbedbfc4411068a9d}, {0xf4f1b4d515acb93b, 0xee92fb5515482d45},
0596 {0x991711052d8bf3c5, 0x751bdd152d4d1c4b}, {0xbf5cd54678eef0b6, 0xd262d45a78a0635e},
0597 {0xef340a98172aace4, 0x86fb897116c87c35}, {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1},
0598 {0xbae0a846d2195712, 0x8974836059cca10a}, {0xe998d258869facd7, 0x2bd1a438703fc94c},
0599 {0x91ff83775423cc06, 0x7b6306a34627ddd0}, {0xb67f6455292cbf08, 0x1a3bc84c17b1d543},
0600 {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94}, {0x8e938662882af53e, 0x547eb47b7282ee9d},
0601 {0xb23867fb2a35b28d, 0xe99e619a4f23aa44}, {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5},
0602 {0x8b3c113c38f9f37e, 0xde83bc408dd3dd05}, {0xae0b158b4738705e, 0x9624ab50b148d446},
0603 {0xd98ddaee19068c76, 0x3badd624dd9b0958}, {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7},
0604 {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d}, {0xd47487cc8470652b, 0x7647c32000696720},
0605 {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074}, {0xa5fb0a17c777cf09, 0xf468107100525891},
0606 {0xcf79cc9db955c2cc, 0x7182148d4066eeb5}, {0x81ac1fe293d599bf, 0xc6f14cd848405531},
0607 {0xa21727db38cb002f, 0xb8ada00e5a506a7d}, {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d},
0608 {0xfd442e4688bd304a, 0x908f4a166d1da664}, {0x9e4a9cec15763e2e, 0x9a598e4e043287ff},
0609 {0xc5dd44271ad3cdba, 0x40eff1e1853f29fe}, {0xf7549530e188c128, 0xd12bee59e68ef47d},
0610 {0x9a94dd3e8cf578b9, 0x82bb74f8301958cf}, {0xc13a148e3032d6e7, 0xe36a52363c1faf02},
0611 {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2}, {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba},
0612 {0xbcb2b812db11a5de, 0x7415d448f6b6f0e8}, {0xebdf661791d60f56, 0x111b495b3464ad22},
0613 {0x936b9fcebb25c995, 0xcab10dd900beec35}, {0xb84687c269ef3bfb, 0x3d5d514f40eea743},
0614 {0xe65829b3046b0afa, 0x0cb4a5a3112a5113}, {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac},
0615 {0xb3f4e093db73a093, 0x59ed216765690f57}, {0xe0f218b8d25088b8, 0x306869c13ec3532d},
0616 {0x8c974f7383725573, 0x1e414218c73a13fc}, {0xafbd2350644eeacf, 0xe5d1929ef90898fb},
0617 {0xdbac6c247d62a583, 0xdf45f746b74abf3a}, {0x894bc396ce5da772, 0x6b8bba8c328eb784},
0618 {0xab9eb47c81f5114f, 0x066ea92f3f326565}, {0xd686619ba27255a2, 0xc80a537b0efefebe},
0619 {0x8613fd0145877585, 0xbd06742ce95f5f37}, {0xa798fc4196e952e7, 0x2c48113823b73705},
0620 {0xd17f3b51fca3a7a0, 0xf75a15862ca504c6}, {0x82ef85133de648c4, 0x9a984d73dbe722fc},
0621 {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb}, {0xcc963fee10b7d1b3, 0x318df905079926a9},
0622 {0xffbbcfe994e5c61f, 0xfdf17746497f7053}, {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634},
0623 {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1}, {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1},
0624 {0x9c1661a651213e2d, 0x06bea10ca65c084f}, {0xc31bfa0fe5698db8, 0x486e494fcff30a63},
0625 {0xf3e2f893dec3f126, 0x5a89dba3c3efccfb}, {0x986ddb5c6b3a76b7, 0xf89629465a75e01d},
0626 {0xbe89523386091465, 0xf6bbb397f1135824}, {0xee2ba6c0678b597f, 0x746aa07ded582e2d},
0627 {0x94db483840b717ef, 0xa8c2a44eb4571cdd}, {0xba121a4650e4ddeb, 0x92f34d62616ce414},
0628 {0xe896a0d7e51e1566, 0x77b020baf9c81d18}, {0x915e2486ef32cd60, 0x0ace1474dc1d122f},
0629 {0xb5b5ada8aaff80b8, 0x0d819992132456bb}, {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a},
0630 {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3},
0631 {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf}, {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c},
0632 {0xad4ab7112eb3929d, 0x86c16c98d2c953c7}, {0xd89d64d57a607744, 0xe871c7bf077ba8b8},
0633 {0x87625f056c7c4a8b, 0x11471cd764ad4973}, {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0},
0634 {0xd389b47879823479, 0x4aff1d108d4ec2c4}, {0x843610cb4bf160cb, 0xcedf722a585139bb},
0635 {0xa54394fe1eedb8fe, 0xc2974eb4ee658829}, {0xce947a3da6a9273e, 0x733d226229feea33},
0636 {0x811ccc668829b887, 0x0806357d5a3f5260}, {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8},
0637 {0xc9bcff6034c13052, 0xfc89b393dd02f0b6}, {0xfc2c3f3841f17c67, 0xbbac2078d443ace3},
0638 {0x9d9ba7832936edc0, 0xd54b944b84aa4c0e}, {0xc5029163f384a931, 0x0a9e795e65d4df12},
0639 {0xf64335bcf065d37d, 0x4d4617b5ff4a16d6}, {0x99ea0196163fa42e, 0x504bced1bf8e4e46},
0640 {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7}, {0xf07da27a82c37088, 0x5d767327bb4e5a4d},
0641 {0x964e858c91ba2655, 0x3a6a07f8d510f870}, {0xbbe226efb628afea, 0x890489f70a55368c},
0642 {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f}, {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e},
0643 {0xb77ada0617e3bbcb, 0x09ce6ebb40173745}, {0xe55990879ddcaabd, 0xcc420a6a101d0516},
0644 {0x8f57fa54c2a9eab6, 0x9fa946824a12232e}, {0xb32df8e9f3546564, 0x47939822dc96abfa},
0645 {0xdff9772470297ebd, 0x59787e2b93bc56f8}, {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b},
0646 {0xaefae51477a06b03, 0xede622920b6b23f2}, {0xdab99e59958885c4, 0xe95fab368e45ecee},
0647 {0x88b402f7fd75539b, 0x11dbcb0218ebb415}, {0xaae103b5fcd2a881, 0xd652bdc29f26a11a},
0648 {0xd59944a37c0752a2, 0x4be76d3346f04960}, {0x857fcae62d8493a5, 0x6f70a4400c562ddc},
0649 {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953}, {0xd097ad07a71f26b2, 0x7e2000a41346a7a8},
0650 {0x825ecc24c873782f, 0x8ed400668c0c28c9}, {0xa2f67f2dfa90563b, 0x728900802f0f32fb},
0651 {0xcbb41ef979346bca, 0x4f2b40a03ad2ffba}, {0xfea126b7d78186bc, 0xe2f610c84987bfa9},
0652 {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca}, {0xc6ede63fa05d3143, 0x91503d1c79720dbc},
0653 {0xf8a95fcf88747d94, 0x75a44c6397ce912b}, {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb},
0654 {0xc24452da229b021b, 0xfbe85badce996169}, {0xf2d56790ab41c2a2, 0xfae27299423fb9c4},
0655 {0x97c560ba6b0919a5, 0xdccd879fc967d41b}, {0xbdb6b8e905cb600f, 0x5400e987bbc1c921},
0656 {0xed246723473e3813, 0x290123e9aab23b69}, {0x9436c0760c86e30b, 0xf9a0b6720aaf6522},
0657 {0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, {0xe7958cb87392c2c2, 0xb60b1d1230b20e05},
0658 {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3}, {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4},
0659 {0xe2280b6c20dd5232, 0x25c6da63c38de1b1}, {0x8d590723948a535f, 0x579c487e5a38ad0f},
0660 {0xb0af48ec79ace837, 0x2d835a9df0c6d852}, {0xdcdb1b2798182244, 0xf8e431456cf88e66},
0661 {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900}, {0xac8b2d36eed2dac5, 0xe272467e3d222f40},
0662 {0xd7adf884aa879177, 0x5b0ed81dcc6abb10}, {0x86ccbb52ea94baea, 0x98e947129fc2b4ea},
0663 {0xa87fea27a539e9a5, 0x3f2398d747b36225}, {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae},
0664 {0x83a3eeeef9153e89, 0x1953cf68300424ad}, {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8},
0665 {0xcdb02555653131b6, 0x3792f412cb06794e}, {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1},
0666 {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5}, {0xc8de047564d20a8b, 0xf245825a5a445276},
0667 {0xfb158592be068d2e, 0xeed6e2f0f0d56713}, {0x9ced737bb6c4183d, 0x55464dd69685606c},
0668 {0xc428d05aa4751e4c, 0xaa97e14c3c26b887}, {0xf53304714d9265df, 0xd53dd99f4b3066a9},
0669 {0x993fe2c6d07b7fab, 0xe546a8038efe402a}, {0xbf8fdb78849a5f96, 0xde98520472bdd034},
0670 {0xef73d256a5c0f77c, 0x963e66858f6d4441}, {0x95a8637627989aad, 0xdde7001379a44aa9},
0671 {0xbb127c53b17ec159, 0x5560c018580d5d53}, {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7},
0672 {0x9226712162ab070d, 0xcab3961304ca70e9}, {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23},
0673 {0xe45c10c42a2b3b05, 0x8cb89a7db77c506b}, {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243},
0674 {0xb267ed1940f1c61c, 0x55f038b237591ed4}, {0xdf01e85f912e37a3, 0x6b6c46dec52f6689},
0675 {0x8b61313bbabce2c6, 0x2323ac4b3b3da016}, {0xae397d8aa96c1b77, 0xabec975e0a0d081b},
0676 {0xd9c7dced53c72255, 0x96e7bd358c904a22}, {0x881cea14545c7575, 0x7e50d64177da2e55},
0677 {0xaa242499697392d2, 0xdde50bd1d5d0b9ea}, {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865},
0678 {0x84ec3c97da624ab4, 0xbd5af13bef0b113f}, {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f},
0679 {0xcfb11ead453994ba, 0x67de18eda5814af3}, {0x81ceb32c4b43fcf4, 0x80eacf948770ced8},
0680 {0xa2425ff75e14fc31, 0xa1258379a94d028e}, {0xcad2f7f5359a3b3e, 0x096ee45813a04331},
0681 {0xfd87b5f28300ca0d, 0x8bca9d6e188853fd}, {0x9e74d1b791e07e48, 0x775ea264cf55347e},
0682 {0xc612062576589dda, 0x95364afe032a819e}, {0xf79687aed3eec551, 0x3a83ddbd83f52205},
0683 {0x9abe14cd44753b52, 0xc4926a9672793543}, {0xc16d9a0095928a27, 0x75b7053c0f178294},
0684 {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, {0x971da05074da7bee, 0xd3f6fc16ebca5e04},
0685 {0xbce5086492111aea, 0x88f4bb1ca6bcf585}, {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6},
0686 {0x9392ee8e921d5d07, 0x3aff322e62439fd0}, {0xb877aa3236a4b449, 0x09befeb9fad487c3},
0687 {0xe69594bec44de15b, 0x4c2ebe687989a9b4}, {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11},
0688 {0xb424dc35095cd80f, 0x538484c19ef38c95}, {0xe12e13424bb40e13, 0x2865a5f206b06fba},
0689 {0x8cbccc096f5088cb, 0xf93f87b7442e45d4}, {0xafebff0bcb24aafe, 0xf78f69a51539d749},
0690 {0xdbe6fecebdedd5be, 0xb573440e5a884d1c}, {0x89705f4136b4a597, 0x31680a88f8953031},
0691 {0xabcc77118461cefc, 0xfdc20d2b36ba7c3e}, {0xd6bf94d5e57a42bc, 0x3d32907604691b4d},
0692 {0x8637bd05af6c69b5, 0xa63f9a49c2c1b110}, {0xa7c5ac471b478423, 0x0fcf80dc33721d54},
0693 {0xd1b71758e219652b, 0xd3c36113404ea4a9}, {0x83126e978d4fdf3b, 0x645a1cac083126ea},
0694 {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4}, {0xcccccccccccccccc, 0xcccccccccccccccd},
0695 {0x8000000000000000, 0x0000000000000000}, {0xa000000000000000, 0x0000000000000000},
0696 {0xc800000000000000, 0x0000000000000000}, {0xfa00000000000000, 0x0000000000000000},
0697 {0x9c40000000000000, 0x0000000000000000}, {0xc350000000000000, 0x0000000000000000},
0698 {0xf424000000000000, 0x0000000000000000}, {0x9896800000000000, 0x0000000000000000},
0699 {0xbebc200000000000, 0x0000000000000000}, {0xee6b280000000000, 0x0000000000000000},
0700 {0x9502f90000000000, 0x0000000000000000}, {0xba43b74000000000, 0x0000000000000000},
0701 {0xe8d4a51000000000, 0x0000000000000000}, {0x9184e72a00000000, 0x0000000000000000},
0702 {0xb5e620f480000000, 0x0000000000000000}, {0xe35fa931a0000000, 0x0000000000000000},
0703 {0x8e1bc9bf04000000, 0x0000000000000000}, {0xb1a2bc2ec5000000, 0x0000000000000000},
0704 {0xde0b6b3a76400000, 0x0000000000000000}, {0x8ac7230489e80000, 0x0000000000000000},
0705 {0xad78ebc5ac620000, 0x0000000000000000}, {0xd8d726b7177a8000, 0x0000000000000000},
0706 {0x878678326eac9000, 0x0000000000000000}, {0xa968163f0a57b400, 0x0000000000000000},
0707 {0xd3c21bcecceda100, 0x0000000000000000}, {0x84595161401484a0, 0x0000000000000000},
0708 {0xa56fa5b99019a5c8, 0x0000000000000000}, {0xcecb8f27f4200f3a, 0x0000000000000000},
0709 {0x813f3978f8940984, 0x4000000000000000}, {0xa18f07d736b90be5, 0x5000000000000000},
0710 {0xc9f2c9cd04674ede, 0xa400000000000000}, {0xfc6f7c4045812296, 0x4d00000000000000},
0711 {0x9dc5ada82b70b59d, 0xf020000000000000}, {0xc5371912364ce305, 0x6c28000000000000},
0712 {0xf684df56c3e01bc6, 0xc732000000000000}, {0x9a130b963a6c115c, 0x3c7f400000000000},
0713 {0xc097ce7bc90715b3, 0x4b9f100000000000}, {0xf0bdc21abb48db20, 0x1e86d40000000000},
0714 {0x96769950b50d88f4, 0x1314448000000000}, {0xbc143fa4e250eb31, 0x17d955a000000000},
0715 {0xeb194f8e1ae525fd, 0x5dcfab0800000000}, {0x92efd1b8d0cf37be, 0x5aa1cae500000000},
0716 {0xb7abc627050305ad, 0xf14a3d9e40000000}, {0xe596b7b0c643c719, 0x6d9ccd05d0000000},
0717 {0x8f7e32ce7bea5c6f, 0xe4820023a2000000}, {0xb35dbf821ae4f38b, 0xdda2802c8a800000},
0718 {0xe0352f62a19e306e, 0xd50b2037ad200000}, {0x8c213d9da502de45, 0x4526f422cc340000},
0719 {0xaf298d050e4395d6, 0x9670b12b7f410000}, {0xdaf3f04651d47b4c, 0x3c0cdd765f114000},
0720 {0x88d8762bf324cd0f, 0xa5880a69fb6ac800}, {0xab0e93b6efee0053, 0x8eea0d047a457a00},
0721 {0xd5d238a4abe98068, 0x72a4904598d6d880}, {0x85a36366eb71f041, 0x47a6da2b7f864750},
0722 {0xa70c3c40a64e6c51, 0x999090b65f67d924}, {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d},
0723 {0x82818f1281ed449f, 0xbff8f10e7a8921a5}, {0xa321f2d7226895c7, 0xaff72d52192b6a0e},
0724 {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764491}, {0xfee50b7025c36a08, 0x02f236d04753d5b5},
0725 {0x9f4f2726179a2245, 0x01d762422c946591}, {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef6},
0726 {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb3}, {0x9b934c3b330c8577, 0x63cc55f49f88eb30},
0727 {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fc}, {0xf316271c7fc3908a, 0x8bef464e3945ef7b},
0728 {0x97edd871cfda3a56, 0x97758bf0e3cbb5ad}, {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea318},
0729 {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bde}, {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6b},
0730 {0xb975d6b6ee39e436, 0xb3e2fd538e122b45}, {0xe7d34c64a9c85d44, 0x60dbbca87196b617},
0731 {0x90e40fbeea1d3a4a, 0xbc8955e946fe31ce}, {0xb51d13aea4a488dd, 0x6babab6398bdbe42},
0732 {0xe264589a4dcdab14, 0xc696963c7eed2dd2}, {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca3},
0733 {0xb0de65388cc8ada8, 0x3b25a55f43294bcc}, {0xdd15fe86affad912, 0x49ef0eb713f39ebf},
0734 {0x8a2dbf142dfcc7ab, 0x6e3569326c784338}, {0xacb92ed9397bf996, 0x49c2c37f07965405},
0735 {0xd7e77a8f87daf7fb, 0xdc33745ec97be907}, {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a4},
0736 {0xa8acd7c0222311bc, 0xc40832ea0d68ce0d}, {0xd2d80db02aabd62b, 0xf50a3fa490c30191},
0737 {0x83c7088e1aab65db, 0x792667c6da79e0fb}, {0xa4b8cab1a1563f52, 0x577001b891185939},
0738 {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87}, {0x80b05e5ac60b6178, 0x544f8158315b05b5},
0739 {0xa0dc75f1778e39d6, 0x696361ae3db1c722}, {0xc913936dd571c84c, 0x03bc3a19cd1e38ea},
0740 {0xfb5878494ace3a5f, 0x04ab48a04065c724}, {0x9d174b2dcec0e47b, 0x62eb0d64283f9c77},
0741 {0xc45d1df942711d9a, 0x3ba5d0bd324f8395}, {0xf5746577930d6500, 0xca8f44ec7ee3647a},
0742 {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecc}, {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67f},
0743 {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101f}, {0x95d04aee3b80ece5, 0xbba1f1d158724a13},
0744 {0xbb445da9ca61281f, 0x2a8a6e45ae8edc98}, {0xea1575143cf97226, 0xf52d09d71a3293be},
0745 {0x924d692ca61be758, 0x593c2626705f9c57}, {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836d},
0746 {0xe498f455c38b997a, 0x0b6dfb9c0f956448}, {0x8edf98b59a373fec, 0x4724bd4189bd5ead},
0747 {0xb2977ee300c50fe7, 0x58edec91ec2cb658}, {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ee},
0748 {0x8b865b215899f46c, 0xbd79e0d20082ee75}, {0xae67f1e9aec07187, 0xecd8590680a3aa12},
0749 {0xda01ee641a708de9, 0xe80e6f4820cc9496}, {0x884134fe908658b2, 0x3109058d147fdcde},
0750 {0xaa51823e34a7eede, 0xbd4b46f0599fd416}, {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91b},
0751 {0x850fadc09923329e, 0x03e2cf6bc604ddb1}, {0xa6539930bf6bff45, 0x84db8346b786151d},
0752 {0xcfe87f7cef46ff16, 0xe612641865679a64}, {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07f},
0753 {0xa26da3999aef7749, 0xe3be5e330f38f09e}, {0xcb090c8001ab551c, 0x5cadf5bfd3072cc6},
0754 {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f7}, {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afb},
0755 {0xc646d63501a1511d, 0xb281e1fd541501b9}, {0xf7d88bc24209a565, 0x1f225a7ca91a4227},
0756 {0x9ae757596946075f, 0x3375788de9b06959}, {0xc1a12d2fc3978937, 0x0052d6b1641c83af},
0757 {0xf209787bb47d6b84, 0xc0678c5dbd23a49b}, {0x9745eb4d50ce6332, 0xf840b7ba963646e1},
0758 {0xbd176620a501fbff, 0xb650e5a93bc3d899}, {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebf},
0759 {0x93ba47c980e98cdf, 0xc66f336c36b10138}, {0xb8a8d9bbe123f017, 0xb80b0047445d4185},
0760 {0xe6d3102ad96cec1d, 0xa60dc059157491e6}, {0x9043ea1ac7e41392, 0x87c89837ad68db30},
0761 {0xb454e4a179dd1877, 0x29babe4598c311fc}, {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67b},
0762 {0x8ce2529e2734bb1d, 0x1899e4a65f58660d}, {0xb01ae745b101e9e4, 0x5ec05dcff72e7f90},
0763 {0xdc21a1171d42645d, 0x76707543f4fa1f74}, {0x899504ae72497eba, 0x6a06494a791c53a9},
0764 {0xabfa45da0edbde69, 0x0487db9d17636893}, {0xd6f8d7509292d603, 0x45a9d2845d3c42b7},
0765 {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3}, {0xa7f26836f282b732, 0x8e6cac7768d7141f},
0766 {0xd1ef0244af2364ff, 0x3207d795430cd927}, {0x8335616aed761f1f, 0x7f44e6bd49e807b9},
0767 {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a7}, {0xcd036837130890a1, 0x36dba887c37a8c10},
0768 {0x802221226be55a64, 0xc2494954da2c978a}, {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6d},
0769 {0xc83553c5c8965d3d, 0x6f92829494e5acc8}, {0xfa42a8b73abbf48c, 0xcb772339ba1f17fa},
0770 {0x9c69a97284b578d7, 0xff2a760414536efc}, {0xc38413cf25e2d70d, 0xfef5138519684abb},
0771 {0xf46518c2ef5b8cd1, 0x7eb258665fc25d6a}, {0x98bf2f79d5993802, 0xef2f773ffbd97a62},
0772 {0xbeeefb584aff8603, 0xaafb550ffacfd8fb}, {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf39},
0773 {0x952ab45cfa97a0b2, 0xdd945a747bf26184}, {0xba756174393d88df, 0x94f971119aeef9e5},
0774 {0xe912b9d1478ceb17, 0x7a37cd5601aab85e}, {0x91abb422ccb812ee, 0xac62e055c10ab33b},
0775 {0xb616a12b7fe617aa, 0x577b986b314d600a}, {0xe39c49765fdf9d94, 0xed5a7e85fda0b80c},
0776 {0x8e41ade9fbebc27d, 0x14588f13be847308}, {0xb1d219647ae6b31c, 0x596eb2d8ae258fc9},
0777 {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bc}, {0x8aec23d680043bee, 0x25de7bb9480d5855},
0778 {0xada72ccc20054ae9, 0xaf561aa79a10ae6b}, {0xd910f7ff28069da4, 0x1b2ba1518094da05},
0779 {0x87aa9aff79042286, 0x90fb44d2f05d0843}, {0xa99541bf57452b28, 0x353a1607ac744a54},
0780 {0xd3fa922f2d1675f2, 0x42889b8997915ce9}, {0x847c9b5d7c2e09b7, 0x69956135febada12},
0781 {0xa59bc234db398c25, 0x43fab9837e699096}, {0xcf02b2c21207ef2e, 0x94f967e45e03f4bc},
0782 {0x8161afb94b44f57d, 0x1d1be0eebac278f6}, {0xa1ba1ba79e1632dc, 0x6462d92a69731733},
0783 {0xca28a291859bbf93, 0x7d7b8f7503cfdcff}, {0xfcb2cb35e702af78, 0x5cda735244c3d43f},
0784 {0x9defbf01b061adab, 0x3a0888136afa64a8}, {0xc56baec21c7a1916, 0x088aaa1845b8fdd1},
0785 {0xf6c69a72a3989f5b, 0x8aad549e57273d46}, {0x9a3c2087a63f6399, 0x36ac54e2f678864c},
0786 {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7de}, {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d6},
0787 {0x969eb7c47859e743, 0x9f644ae5a4b1b326}, {0xbc4665b596706114, 0x873d5d9f0dde1fef},
0788 {0xeb57ff22fc0c7959, 0xa90cb506d155a7eb}, {0x9316ff75dd87cbd8, 0x09a7f12442d588f3},
0789 {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb30}, {0xe5d3ef282a242e81, 0x8f1668c8a86da5fb},
0790 {0x8fa475791a569d10, 0xf96e017d694487bd}, {0xb38d92d760ec4455, 0x37c981dcc395a9ad},
0791 {0xe070f78d3927556a, 0x85bbe253f47b1418}, {0x8c469ab843b89562, 0x93956d7478ccec8f},
0792 {0xaf58416654a6babb, 0x387ac8d1970027b3}, {0xdb2e51bfe9d0696a, 0x06997b05fcc0319f},
0793 {0x88fcf317f22241e2, 0x441fece3bdf81f04}, {0xab3c2fddeeaad25a, 0xd527e81cad7626c4},
0794 {0xd60b3bd56a5586f1, 0x8a71e223d8d3b075}, {0x85c7056562757456, 0xf6872d5667844e4a},
0795 {0xa738c6bebb12d16c, 0xb428f8ac016561dc}, {0xd106f86e69d785c7, 0xe13336d701beba53},
0796 {0x82a45b450226b39c, 0xecc0024661173474}, {0xa34d721642b06084, 0x27f002d7f95d0191},
0797 {0xcc20ce9bd35c78a5, 0x31ec038df7b441f5}, {0xff290242c83396ce, 0x7e67047175a15272},
0798 {0x9f79a169bd203e41, 0x0f0062c6e984d387}, {0xc75809c42c684dd1, 0x52c07b78a3e60869},
0799 {0xf92e0c3537826145, 0xa7709a56ccdf8a83}, {0x9bbcc7a142b17ccb, 0x88a66076400bb692},
0800 {0xc2abf989935ddbfe, 0x6acff893d00ea436}, {0xf356f7ebf83552fe, 0x0583f6b8c4124d44},
0801 {0x98165af37b2153de, 0xc3727a337a8b704b}, {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5d},
0802 {0xeda2ee1c7064130c, 0x1162def06f79df74}, {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba9},
0803 {0xb9a74a0637ce2ee1, 0x6d953e2bd7173693}, {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0438},
0804 {0x910ab1d4db9914a0, 0x1d9c9892400a22a3}, {0xb54d5e4a127f59c8, 0x2503beb6d00cab4c},
0805 {0xe2a0b5dc971f303a, 0x2e44ae64840fd61e}, {0x8da471a9de737e24, 0x5ceaecfed289e5d3},
0806 {0xb10d8e1456105dad, 0x7425a83e872c5f48}, {0xdd50f1996b947518, 0xd12f124e28f7771a},
0807 {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa70}, {0xace73cbfdc0bfb7b, 0x636cc64d1001550c},
0808 {0xd8210befd30efa5a, 0x3c47f7e05401aa4f}, {0x8714a775e3e95c78, 0x65acfaec34810a72},
0809 {0xa8d9d1535ce3b396, 0x7f1839a741a14d0e}, {0xd31045a8341ca07c, 0x1ede48111209a051},
0810 {0x83ea2b892091e44d, 0x934aed0aab460433}, {0xa4e4b66b68b65d60, 0xf81da84d56178540},
0811 {0xce1de40642e3f4b9, 0x36251260ab9d668f}, {0x80d2ae83e9ce78f3, 0xc1d72b7c6b42601a},
0812 {0xa1075a24e4421730, 0xb24cf65b8612f820}, {0xc94930ae1d529cfc, 0xdee033f26797b628},
0813 {0xfb9b7cd9a4a7443c, 0x169840ef017da3b2}, {0x9d412e0806e88aa5, 0x8e1f289560ee864f},
0814 {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e3}, {0xf5b5d7ec8acb58a2, 0xae10af696774b1dc},
0815 {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef2a}, {0xbff610b0cc6edd3f, 0x17fd090a58d32af4},
0816 {0xeff394dcff8a948e, 0xddfc4b4cef07f5b1}, {0x95f83d0a1fb69cd9, 0x4abdaf101564f98f},
0817 {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f2}, {0xea53df5fd18d5513, 0x84c86189216dc5ee},
0818 {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb5}, {0xb7118682dbb66a77, 0x3fbc8c33221dc2a2},
0819 {0xe4d5e82392a40515, 0x0fabaf3feaa5334b}, {0x8f05b1163ba6832d, 0x29cb4d87f2a7400f},
0820 {0xb2c71d5bca9023f8, 0x743e20e9ef511013}, {0xdf78e4b2bd342cf6, 0x914da9246b255417},
0821 {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548f}, {0xae9672aba3d0c320, 0xa184ac2473b529b2},
0822 {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741f}, {0x8865899617fb1871, 0x7e2fa67c7a658893},
0823 {0xaa7eebfb9df9de8d, 0xddbb901b98feeab8}, {0xd51ea6fa85785631, 0x552a74227f3ea566},
0824 {0x8533285c936b35de, 0xd53a88958f872760}, {0xa67ff273b8460356, 0x8a892abaf368f138},
0825 {0xd01fef10a657842c, 0x2d2b7569b0432d86}, {0x8213f56a67f6b29b, 0x9c3b29620e29fc74},
0826 {0xa298f2c501f45f42, 0x8349f3ba91b47b90}, {0xcb3f2f7642717713, 0x241c70a936219a74},
0827 {0xfe0efb53d30dd4d7, 0xed238cd383aa0111}, {0x9ec95d1463e8a506, 0xf4363804324a40ab},
0828 {0xc67bb4597ce2ce48, 0xb143c6053edcd0d6}, {0xf81aa16fdc1b81da, 0xdd94b7868e94050b},
0829 {0x9b10a4e5e9913128, 0xca7cf2b4191c8327}, {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f1},
0830 {0xf24a01a73cf2dccf, 0xbc633b39673c8ced}, {0x976e41088617ca01, 0xd5be0503e085d814},
0831 {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e19}, {0xec9c459d51852ba2, 0xddf8e7d60ed1219f},
0832 {0x93e1ab8252f33b45, 0xcabb90e5c942b504}, {0xb8da1662e7b00a17, 0x3d6a751f3b936244},
0833 {0xe7109bfba19c0c9d, 0x0cc512670a783ad5}, {0x906a617d450187e2, 0x27fb2b80668b24c6},
0834 {0xb484f9dc9641e9da, 0xb1f9f660802dedf7}, {0xe1a63853bbd26451, 0x5e7873f8a0396974},
0835 {0x8d07e33455637eb2, 0xdb0b487b6423e1e9}, {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda63},
0836 {0xdc5c5301c56b75f7, 0x7641a140cc7810fc}, {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9e},
0837 {0xac2820d9623bf429, 0x546345fa9fbdcd45}, {0xd732290fbacaf133, 0xa97c177947ad4096},
0838 {0x867f59a9d4bed6c0, 0x49ed8eabcccc485e}, {0xa81f301449ee8c70, 0x5c68f256bfff5a75},
0839 {0xd226fc195c6a2f8c, 0x73832eec6fff3112}, {0x83585d8fd9c25db7, 0xc831fd53c5ff7eac},
0840 {0xa42e74f3d032f525, 0xba3e7ca8b77f5e56}, {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35ec},
0841 {0x80444b5e7aa7cf85, 0x7980d163cf5b81b4}, {0xa0555e361951c366, 0xd7e105bcc3326220},
0842 {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa8}, {0xfa856334878fc150, 0xb14f98f6f0feb952},
0843 {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d4}, {0xc3b8358109e84f07, 0x0a862f80ec4700c9},
0844 {0xf4a642e14c6262c8, 0xcd27bb612758c0fb}, {0x98e7e9cccfbd7dbd, 0x8038d51cb897789d},
0845 {0xbf21e44003acdd2c, 0xe0470a63e6bd56c4}, {0xeeea5d5004981478, 0x1858ccfce06cac75},
0846 {0x95527a5202df0ccb, 0x0f37801e0c43ebc9}, {0xbaa718e68396cffd, 0xd30560258f54e6bb},
0847 {0xe950df20247c83fd, 0x47c6b82ef32a206a}, {0x91d28b7416cdd27e, 0x4cdc331d57fa5442},
0848 {0xb6472e511c81471d, 0xe0133fe4adf8e953}, {0xe3d8f9e563a198e5, 0x58180fddd97723a7},
0849 {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7649}, {0xb201833b35d63f73, 0x2cd2cc6551e513db},
0850 {0xde81e40a034bcf4f, 0xf8077f7ea65e58d2}, {0x8b112e86420f6191, 0xfb04afaf27faf783},
0851 {0xadd57a27d29339f6, 0x79c5db9af1f9b564}, {0xd94ad8b1c7380874, 0x18375281ae7822bd},
0852 {0x87cec76f1c830548, 0x8f2293910d0b15b6}, {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb23},
0853 {0xd433179d9c8cb841, 0x5fa60692a46151ec}, {0x849feec281d7f328, 0xdbc7c41ba6bcd334},
0854 {0xa5c7ea73224deff3, 0x12b9b522906c0801}, {0xcf39e50feae16bef, 0xd768226b34870a01},
0855 {0x81842f29f2cce375, 0xe6a1158300d46641}, {0xa1e53af46f801c53, 0x60495ae3c1097fd1},
0856 {0xca5e89b18b602368, 0x385bb19cb14bdfc5}, {0xfcf62c1dee382c42, 0x46729e03dd9ed7b6},
0857 {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d2}, {0xc5a05277621be293, 0xc7098b7305241886},
0858 {0xf70867153aa2db38, 0xb8cbee4fc66d1ea8}};
0859 };
0860
0861 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
0862
0863 template <bool b> constexpr int cache_holder_ieee754_binary64_impl<b>::cache_bits;
0864 template <bool b> constexpr int cache_holder_ieee754_binary64_impl<b>::min_k;
0865 template <bool b> constexpr int cache_holder_ieee754_binary64_impl<b>::max_k;
0866 template <bool b> constexpr typename cache_holder_ieee754_binary64_impl<b>::cache_entry_type cache_holder_ieee754_binary64_impl<b>::cache[];
0867
0868 #endif
0869
0870 #if (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
0871 using cache_holder_ieee754_binary64 = cache_holder_ieee754_binary64_impl<true>;
0872 #endif
0873
0874
0875
0876
0877
0878
0879 template <typename Float, typename FloatTraits = dragonbox_float_traits<Float>>
0880 struct impl;
0881
0882 namespace policy_impl {
0883
0884 namespace sign {
0885 struct base {};
0886
0887 struct ignore : base
0888 {
0889 using sign_policy = ignore;
0890 static constexpr bool return_has_sign = false;
0891
0892 template <typename SignedSignificandBits, typename ReturnType>
0893 static BOOST_CXX14_CONSTEXPR void handle_sign(SignedSignificandBits, ReturnType&) noexcept {}
0894 };
0895
0896 struct return_sign : base
0897 {
0898 using sign_policy = return_sign;
0899 static constexpr bool return_has_sign = true;
0900
0901 template <typename SignedSignificandBits, typename ReturnType>
0902 static BOOST_CXX14_CONSTEXPR void handle_sign(SignedSignificandBits s, ReturnType& r) noexcept
0903 {
0904 r.is_negative = s.is_negative();
0905 }
0906 };
0907 }
0908
0909
0910 namespace trailing_zero {
0911 struct base {};
0912
0913 struct ignore : base
0914 {
0915 using trailing_zero_policy = ignore;
0916 static constexpr bool report_trailing_zeros = false;
0917
0918 template <typename Impl, typename ReturnType>
0919 static BOOST_CXX14_CONSTEXPR void on_trailing_zeros(ReturnType&) noexcept {}
0920
0921 template <typename Impl, typename ReturnType>
0922 static BOOST_CXX14_CONSTEXPR void no_trailing_zeros(ReturnType&) noexcept {}
0923 };
0924
0925 struct remove : base
0926 {
0927 using trailing_zero_policy = remove;
0928 static constexpr bool report_trailing_zeros = false;
0929
0930 template <typename Impl, typename ReturnType>
0931 BOOST_FORCEINLINE static void on_trailing_zeros(ReturnType& r) noexcept
0932 {
0933 r.exponent += Impl::remove_trailing_zeros(r.significand);
0934 }
0935
0936 template <typename Impl, typename ReturnType>
0937 static BOOST_CXX14_CONSTEXPR void no_trailing_zeros(ReturnType&) noexcept {}
0938 };
0939
0940 struct report : base
0941 {
0942 using trailing_zero_policy = report;
0943 static constexpr bool report_trailing_zeros = true;
0944
0945 template <typename Impl, typename ReturnType>
0946 static BOOST_CXX14_CONSTEXPR void on_trailing_zeros(ReturnType& r) noexcept
0947 {
0948 r.may_have_trailing_zeros = true;
0949 }
0950
0951 template <typename Impl, typename ReturnType>
0952 static BOOST_CXX14_CONSTEXPR void no_trailing_zeros(ReturnType& r) noexcept
0953 {
0954 r.may_have_trailing_zeros = false;
0955 }
0956 };
0957 }
0958
0959
0960 namespace decimal_to_binary_rounding {
0961 struct base {};
0962
0963 enum class tag_t
0964 {
0965 to_nearest,
0966 left_closed_directed,
0967 right_closed_directed
0968 };
0969
0970 namespace interval_type {
0971 struct symmetric_boundary
0972 {
0973 static constexpr bool is_symmetric = true;
0974 bool is_closed;
0975 constexpr bool include_left_endpoint() const noexcept { return is_closed; }
0976 constexpr bool include_right_endpoint() const noexcept { return is_closed; }
0977 };
0978
0979 struct asymmetric_boundary
0980 {
0981 static constexpr bool is_symmetric = false;
0982 bool is_left_closed;
0983 constexpr bool include_left_endpoint() const noexcept { return is_left_closed; }
0984 constexpr bool include_right_endpoint() const noexcept { return !is_left_closed; }
0985 };
0986
0987 struct closed
0988 {
0989 static constexpr bool is_symmetric = true;
0990 static constexpr bool include_left_endpoint() noexcept { return true; }
0991 static constexpr bool include_right_endpoint() noexcept { return true; }
0992 };
0993
0994 struct open
0995 {
0996 static constexpr bool is_symmetric = true;
0997 static constexpr bool include_left_endpoint() noexcept { return false; }
0998 static constexpr bool include_right_endpoint() noexcept { return false; }
0999 };
1000
1001 struct left_closed_right_open
1002 {
1003 static constexpr bool is_symmetric = false;
1004 static constexpr bool include_left_endpoint() noexcept { return true; }
1005 static constexpr bool include_right_endpoint() noexcept { return false; }
1006 };
1007
1008 struct right_closed_left_open
1009 {
1010 static constexpr bool is_symmetric = false;
1011 static constexpr bool include_left_endpoint() noexcept { return false; }
1012 static constexpr bool include_right_endpoint() noexcept { return true; }
1013 };
1014 }
1015
1016 template <typename T>
1017 struct return_type : return_type<decltype(&T::operator())>
1018 {};
1019
1020 struct nearest_to_even : base
1021 {
1022 using decimal_to_binary_rounding_policy = nearest_to_even;
1023 static constexpr auto tag = tag_t::to_nearest;
1024 using normal_interval_type = interval_type::symmetric_boundary;
1025 using shorter_interval_type = interval_type::closed;
1026
1027 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1028 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits, Func f) noexcept
1029 {
1030 return f(nearest_to_even{});
1031 }
1032
1033 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1034 BOOST_FORCEINLINE static constexpr ReturnType
1035 invoke_normal_interval_case(SignedSignificandBits s, Func&& f) noexcept
1036 {
1037 return f(s.has_even_significand_bits());
1038 }
1039
1040 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1041 BOOST_FORCEINLINE static constexpr ReturnType
1042 invoke_shorter_interval_case(SignedSignificandBits, Func&& f) noexcept
1043 {
1044 return f();
1045 }
1046 };
1047
1048 struct nearest_to_odd : base
1049 {
1050 using decimal_to_binary_rounding_policy = nearest_to_odd;
1051 static constexpr auto tag = tag_t::to_nearest;
1052 using normal_interval_type = interval_type::symmetric_boundary;
1053 using shorter_interval_type = interval_type::open;
1054
1055 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1056 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits, Func&& f) noexcept
1057 {
1058 return f(nearest_to_odd{});
1059 }
1060
1061 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1062 BOOST_FORCEINLINE static constexpr ReturnType
1063 invoke_normal_interval_case(SignedSignificandBits s, Func&& f) noexcept
1064 {
1065 return f(!s.has_even_significand_bits());
1066 }
1067
1068 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1069 BOOST_FORCEINLINE static constexpr ReturnType
1070 invoke_shorter_interval_case(SignedSignificandBits, Func&& f) noexcept
1071 {
1072 return f();
1073 }
1074 };
1075
1076 struct nearest_toward_plus_infinity : base
1077 {
1078 using decimal_to_binary_rounding_policy = nearest_toward_plus_infinity;
1079 static constexpr auto tag = tag_t::to_nearest;
1080 using normal_interval_type = interval_type::asymmetric_boundary;
1081 using shorter_interval_type = interval_type::asymmetric_boundary;
1082
1083 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1084 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits, Func&& f) noexcept
1085 {
1086 return f(nearest_toward_plus_infinity{});
1087 }
1088
1089 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1090 BOOST_FORCEINLINE static constexpr ReturnType
1091 invoke_normal_interval_case(SignedSignificandBits s, Func&& f) noexcept
1092 {
1093 return f(!s.is_negative());
1094 }
1095
1096 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1097 BOOST_FORCEINLINE static constexpr ReturnType
1098 invoke_shorter_interval_case(SignedSignificandBits s, Func&& f) noexcept
1099 {
1100 return f(!s.is_negative());
1101 }
1102 };
1103
1104 struct nearest_toward_minus_infinity : base
1105 {
1106 using decimal_to_binary_rounding_policy = nearest_toward_minus_infinity;
1107 static constexpr auto tag = tag_t::to_nearest;
1108 using normal_interval_type = interval_type::asymmetric_boundary;
1109 using shorter_interval_type = interval_type::asymmetric_boundary;
1110
1111 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1112 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits, Func&& f) noexcept
1113 {
1114 return f(nearest_toward_minus_infinity{});
1115 }
1116
1117 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1118 BOOST_FORCEINLINE static constexpr ReturnType
1119 invoke_normal_interval_case(SignedSignificandBits s, Func&& f) noexcept
1120 {
1121 return f(s.is_negative());
1122 }
1123
1124 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1125 BOOST_FORCEINLINE static constexpr ReturnType
1126 invoke_shorter_interval_case(SignedSignificandBits s, Func&& f) noexcept
1127 {
1128 return f(s.is_negative());
1129 }
1130 };
1131
1132 struct nearest_toward_zero : base
1133 {
1134 using decimal_to_binary_rounding_policy = nearest_toward_zero;
1135 static constexpr auto tag = tag_t::to_nearest;
1136 using normal_interval_type = interval_type::right_closed_left_open;
1137 using shorter_interval_type = interval_type::right_closed_left_open;
1138
1139 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1140 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits, Func&& f) noexcept
1141 {
1142 return f(nearest_toward_zero{});
1143 }
1144
1145 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1146 BOOST_FORCEINLINE static constexpr ReturnType
1147 invoke_normal_interval_case(SignedSignificandBits, Func&& f) noexcept
1148 {
1149 return f();
1150 }
1151
1152 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1153 BOOST_FORCEINLINE static constexpr ReturnType
1154 invoke_shorter_interval_case(SignedSignificandBits, Func&& f) noexcept
1155 {
1156 return f();
1157 }
1158 };
1159
1160 struct nearest_away_from_zero : base
1161 {
1162 using decimal_to_binary_rounding_policy = nearest_away_from_zero;
1163 static constexpr auto tag = tag_t::to_nearest;
1164 using normal_interval_type = interval_type::left_closed_right_open;
1165 using shorter_interval_type = interval_type::left_closed_right_open;
1166
1167 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1168 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits, Func&& f) noexcept
1169 {
1170 return f(nearest_away_from_zero{});
1171 }
1172
1173 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1174 BOOST_FORCEINLINE static constexpr ReturnType
1175 invoke_normal_interval_case(SignedSignificandBits, Func&& f) noexcept
1176 {
1177 return f();
1178 }
1179
1180 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1181 BOOST_FORCEINLINE static constexpr ReturnType
1182 invoke_shorter_interval_case(SignedSignificandBits, Func&& f) noexcept
1183 {
1184 return f();
1185 }
1186 };
1187
1188 struct nearest_always_closed
1189 {
1190 static constexpr auto tag = tag_t::to_nearest;
1191 using normal_interval_type = interval_type::closed;
1192 using shorter_interval_type = interval_type::closed;
1193
1194 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1195 BOOST_FORCEINLINE static constexpr ReturnType
1196 invoke_normal_interval_case(SignedSignificandBits, Func&& f) noexcept
1197 {
1198 return f();
1199 }
1200
1201 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1202 BOOST_FORCEINLINE static constexpr ReturnType
1203 invoke_shorter_interval_case(SignedSignificandBits, Func&& f) noexcept
1204 {
1205 return f();
1206 }
1207 };
1208
1209 struct nearest_always_open
1210 {
1211 static constexpr auto tag = tag_t::to_nearest;
1212 using normal_interval_type = interval_type::open;
1213 using shorter_interval_type = interval_type::open;
1214
1215 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1216 BOOST_FORCEINLINE static constexpr ReturnType
1217 invoke_normal_interval_case(SignedSignificandBits, Func&& f) noexcept
1218 {
1219 return f();
1220 }
1221
1222 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1223 BOOST_FORCEINLINE static constexpr ReturnType
1224 invoke_shorter_interval_case(SignedSignificandBits, Func&& f) noexcept
1225 {
1226 return f();
1227 }
1228 };
1229
1230 struct nearest_to_even_static_boundary : base
1231 {
1232 using decimal_to_binary_rounding_policy = nearest_to_even_static_boundary;
1233
1234 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1235 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits s, Func&& f) noexcept
1236 {
1237 if (s.has_even_significand_bits())
1238 {
1239 return f(nearest_always_closed{});
1240 }
1241 else
1242 {
1243 return f(nearest_always_open{});
1244 }
1245 }
1246 };
1247
1248 struct nearest_to_odd_static_boundary : base
1249 {
1250 using decimal_to_binary_rounding_policy = nearest_to_odd_static_boundary;
1251
1252 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1253 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits s, Func&& f) noexcept
1254 {
1255 if (s.has_even_significand_bits())
1256 {
1257 return f(nearest_always_open{});
1258 }
1259 else
1260 {
1261 return f(nearest_always_closed{});
1262 }
1263 }
1264 };
1265 struct nearest_toward_plus_infinity_static_boundary : base
1266 {
1267 using decimal_to_binary_rounding_policy = nearest_toward_plus_infinity_static_boundary;
1268
1269 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1270 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits s, Func&& f) noexcept
1271 {
1272 if (s.is_negative())
1273 {
1274 return f(nearest_toward_zero{});
1275 }
1276 else
1277 {
1278 return f(nearest_away_from_zero{});
1279 }
1280 }
1281 };
1282
1283 struct nearest_toward_minus_infinity_static_boundary : base
1284 {
1285 using decimal_to_binary_rounding_policy = nearest_toward_minus_infinity_static_boundary;
1286
1287 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1288 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits s, Func&& f) noexcept
1289 {
1290 if (s.is_negative())
1291 {
1292 return f(nearest_away_from_zero{});
1293 }
1294 else
1295 {
1296 return f(nearest_toward_zero{});
1297 }
1298 }
1299 };
1300
1301 struct left_closed_directed
1302 {
1303 static constexpr auto tag = tag_t::left_closed_directed;
1304 };
1305 struct right_closed_directed
1306 {
1307 static constexpr auto tag = tag_t::right_closed_directed;
1308 };
1309
1310 struct toward_plus_infinity : base
1311 {
1312 using decimal_to_binary_rounding_policy = toward_plus_infinity;
1313
1314 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1315 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits s, Func&& f) noexcept
1316 {
1317 if (s.is_negative())
1318 {
1319 return f(left_closed_directed{});
1320 }
1321 else
1322 {
1323 return f(right_closed_directed{});
1324 }
1325 }
1326 };
1327
1328 struct toward_minus_infinity : base
1329 {
1330 using decimal_to_binary_rounding_policy = toward_minus_infinity;
1331
1332 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1333 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits s, Func&& f) noexcept
1334 {
1335 if (s.is_negative())
1336 {
1337 return f(right_closed_directed{});
1338 }
1339 else
1340 {
1341 return f(left_closed_directed{});
1342 }
1343 }
1344 };
1345
1346 struct toward_zero : base
1347 {
1348 using decimal_to_binary_rounding_policy = toward_zero;
1349
1350 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1351 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits, Func&& f) noexcept
1352 {
1353 return f(left_closed_directed{});
1354 }
1355 };
1356
1357 struct away_from_zero : base
1358 {
1359 using decimal_to_binary_rounding_policy = away_from_zero;
1360
1361 template <typename ReturnType, typename SignedSignificandBits, typename Func>
1362 BOOST_FORCEINLINE static ReturnType delegate(SignedSignificandBits, Func&& f) noexcept
1363 {
1364 return f(right_closed_directed{});
1365 }
1366 };
1367 }
1368
1369
1370
1371 namespace binary_to_decimal_rounding {
1372 struct base {};
1373
1374 enum class tag_t
1375 {
1376 do_not_care,
1377 to_even,
1378 to_odd,
1379 away_from_zero,
1380 toward_zero
1381 };
1382
1383 struct do_not_care : base
1384 {
1385 using binary_to_decimal_rounding_policy = do_not_care;
1386 static constexpr auto tag = tag_t::do_not_care;
1387
1388 template <typename ReturnType>
1389 static constexpr bool prefer_round_down(ReturnType const&) noexcept
1390 {
1391 return false;
1392 }
1393 };
1394
1395 struct to_even : base
1396 {
1397 using binary_to_decimal_rounding_policy = to_even;
1398 static constexpr auto tag = tag_t::to_even;
1399
1400 template <typename ReturnType>
1401 static constexpr bool prefer_round_down(ReturnType const& r) noexcept
1402 {
1403 return r.significand % 2 != 0;
1404 }
1405 };
1406
1407 struct to_odd : base
1408 {
1409 using binary_to_decimal_rounding_policy = to_odd;
1410 static constexpr auto tag = tag_t::to_odd;
1411
1412 template <typename ReturnType>
1413 static constexpr bool prefer_round_down(ReturnType const& r) noexcept
1414 {
1415 return r.significand % 2 == 0;
1416 }
1417 };
1418
1419 struct away_from_zero : base
1420 {
1421 using binary_to_decimal_rounding_policy = away_from_zero;
1422 static constexpr auto tag = tag_t::away_from_zero;
1423
1424 template <typename ReturnType>
1425 static constexpr bool prefer_round_down(ReturnType const&) noexcept
1426 {
1427 return false;
1428 }
1429 };
1430
1431 struct toward_zero : base
1432 {
1433 using binary_to_decimal_rounding_policy = toward_zero;
1434 static constexpr auto tag = tag_t::toward_zero;
1435
1436 template <typename ReturnType>
1437 static constexpr bool prefer_round_down(ReturnType const&) noexcept
1438 {
1439 return true;
1440 }
1441 };
1442 }
1443
1444
1445 namespace cache {
1446 struct base {};
1447
1448 struct full : base
1449 {
1450 using cache_policy = full;
1451
1452 template <typename FloatFormat, typename cache_format = typename std::conditional<std::is_same<FloatFormat, ieee754_binary32>::value,
1453 cache_holder_ieee754_binary32,
1454 cache_holder_ieee754_binary64>::type>
1455 static constexpr typename cache_format::cache_entry_type get_cache(int k) noexcept
1456 {
1457 return cache_format::cache[std::size_t(k - cache_format::min_k)];
1458 }
1459 };
1460 }
1461 }
1462
1463 namespace policy {
1464 namespace sign {
1465 BOOST_INLINE_VARIABLE constexpr auto ignore = detail::policy_impl::sign::ignore{};
1466 BOOST_INLINE_VARIABLE constexpr auto return_sign = detail::policy_impl::sign::return_sign{};
1467 }
1468
1469 namespace trailing_zero {
1470 BOOST_INLINE_VARIABLE constexpr auto ignore = detail::policy_impl::trailing_zero::ignore{};
1471 BOOST_INLINE_VARIABLE constexpr auto remove = detail::policy_impl::trailing_zero::remove{};
1472 BOOST_INLINE_VARIABLE constexpr auto report = detail::policy_impl::trailing_zero::report{};
1473 }
1474
1475 namespace decimal_to_binary_rounding {
1476 BOOST_INLINE_VARIABLE constexpr auto nearest_to_even =
1477 detail::policy_impl::decimal_to_binary_rounding::nearest_to_even{};
1478 BOOST_INLINE_VARIABLE constexpr auto nearest_to_odd =
1479 detail::policy_impl::decimal_to_binary_rounding::nearest_to_odd{};
1480 BOOST_INLINE_VARIABLE constexpr auto nearest_toward_plus_infinity =
1481 detail::policy_impl::decimal_to_binary_rounding::nearest_toward_plus_infinity{};
1482 BOOST_INLINE_VARIABLE constexpr auto nearest_toward_minus_infinity =
1483 detail::policy_impl::decimal_to_binary_rounding::nearest_toward_minus_infinity{};
1484 BOOST_INLINE_VARIABLE constexpr auto nearest_toward_zero =
1485 detail::policy_impl::decimal_to_binary_rounding::nearest_toward_zero{};
1486 BOOST_INLINE_VARIABLE constexpr auto nearest_away_from_zero =
1487 detail::policy_impl::decimal_to_binary_rounding::nearest_away_from_zero{};
1488
1489 BOOST_INLINE_VARIABLE constexpr auto nearest_to_even_static_boundary =
1490 detail::policy_impl::decimal_to_binary_rounding::nearest_to_even_static_boundary{};
1491 BOOST_INLINE_VARIABLE constexpr auto nearest_to_odd_static_boundary =
1492 detail::policy_impl::decimal_to_binary_rounding::nearest_to_odd_static_boundary{};
1493 BOOST_INLINE_VARIABLE constexpr auto nearest_toward_plus_infinity_static_boundary =
1494 detail::policy_impl::decimal_to_binary_rounding::
1495 nearest_toward_plus_infinity_static_boundary{};
1496 BOOST_INLINE_VARIABLE constexpr auto nearest_toward_minus_infinity_static_boundary =
1497 detail::policy_impl::decimal_to_binary_rounding::
1498 nearest_toward_minus_infinity_static_boundary{};
1499
1500 BOOST_INLINE_VARIABLE constexpr auto toward_plus_infinity =
1501 detail::policy_impl::decimal_to_binary_rounding::toward_plus_infinity{};
1502 BOOST_INLINE_VARIABLE constexpr auto toward_minus_infinity =
1503 detail::policy_impl::decimal_to_binary_rounding::toward_minus_infinity{};
1504 BOOST_INLINE_VARIABLE constexpr auto toward_zero =
1505 detail::policy_impl::decimal_to_binary_rounding::toward_zero{};
1506 BOOST_INLINE_VARIABLE constexpr auto away_from_zero =
1507 detail::policy_impl::decimal_to_binary_rounding::away_from_zero{};
1508 }
1509
1510 namespace binary_to_decimal_rounding {
1511 BOOST_INLINE_VARIABLE constexpr auto do_not_care =
1512 detail::policy_impl::binary_to_decimal_rounding::do_not_care{};
1513 BOOST_INLINE_VARIABLE constexpr auto to_even =
1514 detail::policy_impl::binary_to_decimal_rounding::to_even{};
1515 BOOST_INLINE_VARIABLE constexpr auto to_odd =
1516 detail::policy_impl::binary_to_decimal_rounding::to_odd{};
1517 BOOST_INLINE_VARIABLE constexpr auto away_from_zero =
1518 detail::policy_impl::binary_to_decimal_rounding::away_from_zero{};
1519 BOOST_INLINE_VARIABLE constexpr auto toward_zero =
1520 detail::policy_impl::binary_to_decimal_rounding::toward_zero{};
1521 }
1522
1523 namespace cache {
1524 BOOST_INLINE_VARIABLE constexpr auto full = detail::policy_impl::cache::full{};
1525 }
1526 }
1527
1528
1529
1530
1531
1532 template <typename Float, typename FloatTraits>
1533 struct impl : private FloatTraits, private FloatTraits::format
1534 {
1535 using format = typename FloatTraits::format;
1536 using carrier_uint = typename FloatTraits::carrier_uint;
1537
1538 using FloatTraits::carrier_bits;
1539 using format::significand_bits;
1540 using format::min_exponent;
1541 using format::max_exponent;
1542 using format::exponent_bias;
1543 using format::decimal_digits;
1544
1545 static constexpr int kappa = std::is_same<format, ieee754_binary32>::value ? 1 : 2;
1546 static_assert(kappa >= 1, "Kappa must be >= 1");
1547
1548
1549 static constexpr int min_k_a = -log::floor_log10_pow2_minus_log10_4_over_3(int(max_exponent - significand_bits));
1550 static constexpr int min_k_b = -log::floor_log10_pow2(int(max_exponent - significand_bits)) + kappa;
1551 static constexpr int min_k = min_k_a < min_k_b ? min_k_a : min_k_b;
1552
1553
1554 static constexpr int max_k_a = -log::floor_log10_pow2_minus_log10_4_over_3(int(min_exponent - significand_bits ));
1555 static constexpr int max_k_b = -log::floor_log10_pow2(int(min_exponent - significand_bits)) + kappa;
1556 static constexpr int max_k = max_k_a > max_k_b ? max_k_a : max_k_b;
1557
1558 using cache_format = typename std::conditional<std::is_same<format, ieee754_binary32>::value,
1559 cache_holder_ieee754_binary32,
1560 cache_holder_ieee754_binary64>::type;
1561 using cache_entry_type = typename cache_format::cache_entry_type;
1562 static constexpr auto cache_bits = cache_format::cache_bits;
1563
1564 static constexpr int case_shorter_interval_left_endpoint_lower_threshold = 2;
1565 static BOOST_CXX14_CONSTEXPR const int case_shorter_interval_left_endpoint_upper_threshold = 3;
1566
1567
1568 static constexpr int case_shorter_interval_right_endpoint_lower_threshold = 0;
1569 static BOOST_CXX14_CONSTEXPR const int case_shorter_interval_right_endpoint_upper_threshold = 3;
1570
1571
1572 static constexpr int shorter_interval_tie_lower_threshold =
1573 -log::floor_log5_pow2_minus_log5_3(significand_bits + 4) - 2 - significand_bits;
1574 static constexpr int shorter_interval_tie_upper_threshold =
1575 -log::floor_log5_pow2(significand_bits + 2) - 2 - significand_bits;
1576
1577 struct compute_mul_result
1578 {
1579 carrier_uint result;
1580 bool is_integer;
1581 };
1582
1583 struct compute_mul_parity_result
1584 {
1585 bool parity;
1586 bool is_integer;
1587 };
1588
1589
1590
1591 #if defined(__GNUC__) && (__GNUC__ < 5) && !defined(__clang__)
1592 # pragma GCC diagnostic push
1593 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
1594 #endif
1595
1596 template <typename ReturnType, typename IntervalType, typename TrailingZeroPolicy,
1597 typename BinaryToDecimalRoundingPolicy, typename CachePolicy, typename... AdditionalArgs>
1598 BOOST_CHARCONV_SAFEBUFFERS static ReturnType compute_nearest_normal(carrier_uint const two_fc, const int exponent,
1599 AdditionalArgs... additional_args) noexcept
1600 {
1601
1602
1603
1604
1605 ReturnType ret_value = {};
1606 IntervalType interval_type{additional_args...};
1607
1608
1609 const int minus_k = log::floor_log10_pow2(exponent) - kappa;
1610 const auto cache = CachePolicy::template get_cache<format>(-minus_k);
1611 const int beta = exponent + log::floor_log2_pow10(-minus_k);
1612
1613
1614
1615 const auto deltai = compute_delta(cache, beta);
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626 const auto z_res = compute_mul((two_fc | 1) << beta, cache);
1627 const auto zi = z_res.result;
1628 const auto is_z_integer = z_res.is_integer;
1629
1630
1631
1632
1633
1634 BOOST_CXX14_CONSTEXPR auto big_divisor = compute_power(std::uint32_t(10), kappa + 1);
1635 BOOST_CXX14_CONSTEXPR auto small_divisor = compute_power(std::uint32_t(10), kappa);
1636
1637
1638
1639 #ifdef BOOST_NO_CXX14_CONSTEXPR
1640 ret_value.significand = div::divide_by_pow10<carrier_uint>(kappa + 1, (carrier_uint(1) << (significand_bits + 1)) * big_divisor - 1, zi);
1641 #else
1642 ret_value.significand = div::divide_by_pow10<kappa + 1, carrier_uint, (carrier_uint(1) << (significand_bits + 1)) * big_divisor - 1>(zi);
1643 #endif
1644
1645 auto r = std::uint32_t(zi - big_divisor * ret_value.significand);
1646
1647 if (r < deltai)
1648 {
1649
1650 if (r == 0 && (is_z_integer & !interval_type.include_right_endpoint()))
1651 {
1652 BOOST_IF_CONSTEXPR (BinaryToDecimalRoundingPolicy::tag == policy_impl::binary_to_decimal_rounding::tag_t::do_not_care)
1653 {
1654 ret_value.significand *= 10;
1655 ret_value.exponent = minus_k + kappa;
1656 --ret_value.significand;
1657 TrailingZeroPolicy::template no_trailing_zeros<impl>(ret_value);
1658
1659 return ret_value;
1660 }
1661 else
1662 {
1663 --ret_value.significand;
1664 r = big_divisor;
1665
1666 goto small_divisor_case_label;
1667 }
1668 }
1669 }
1670 else if (r > deltai)
1671 {
1672 goto small_divisor_case_label;
1673 }
1674 else
1675 {
1676
1677
1678
1679 const auto x_res = compute_mul_parity(two_fc - 1, cache, beta);
1680 const auto xi_parity = x_res.parity;
1681 const auto x_is_integer = x_res.is_integer;
1682
1683 if (!(xi_parity | (x_is_integer & interval_type.include_left_endpoint())))
1684 {
1685 goto small_divisor_case_label;
1686 }
1687 }
1688 ret_value.exponent = minus_k + kappa + 1;
1689
1690
1691 TrailingZeroPolicy::template on_trailing_zeros<impl>(ret_value);
1692 return ret_value;
1693
1694
1695
1696
1697
1698
1699 small_divisor_case_label:
1700 TrailingZeroPolicy::template no_trailing_zeros<impl>(ret_value);
1701 ret_value.significand *= 10;
1702 ret_value.exponent = minus_k + kappa;
1703
1704 BOOST_IF_CONSTEXPR (BinaryToDecimalRoundingPolicy::tag == policy_impl::binary_to_decimal_rounding::tag_t::do_not_care)
1705 {
1706
1707
1708
1709
1710
1711 if (!interval_type.include_right_endpoint())
1712 {
1713
1714 if (is_z_integer && div::check_divisibility_and_divide_by_pow10<kappa>(r))
1715 {
1716
1717 ret_value.significand += r - 1;
1718 }
1719 else
1720 {
1721 ret_value.significand += r;
1722 }
1723 }
1724 else
1725 {
1726 ret_value.significand += div::small_division_by_pow10<kappa>(r);
1727 }
1728 }
1729 else
1730 {
1731 auto dist = r - (deltai / 2) + (small_divisor / 2);
1732 const bool approx_y_parity = ((dist ^ (small_divisor / 2)) & 1) != 0;
1733
1734
1735 const bool divisible_by_small_divisor = div::check_divisibility_and_divide_by_pow10<kappa>(dist);
1736
1737
1738 ret_value.significand += dist;
1739
1740 if (divisible_by_small_divisor)
1741 {
1742
1743
1744
1745
1746
1747
1748
1749
1750 const auto y_res = compute_mul_parity(two_fc, cache, beta);
1751 const auto yi_parity = y_res.parity;
1752 const auto is_y_integer = y_res.is_integer;
1753
1754 if (yi_parity != approx_y_parity)
1755 {
1756 --ret_value.significand;
1757 }
1758 else
1759 {
1760
1761
1762
1763 if (BinaryToDecimalRoundingPolicy::prefer_round_down(ret_value) & is_y_integer)
1764 {
1765 --ret_value.significand;
1766 }
1767 }
1768 }
1769 }
1770
1771 return ret_value;
1772 }
1773
1774 template <typename ReturnType, typename IntervalType, typename TrailingZeroPolicy,
1775 typename BinaryToDecimalRoundingPolicy, typename CachePolicy, typename... AdditionalArgs>
1776 BOOST_CHARCONV_SAFEBUFFERS static ReturnType compute_nearest_shorter(const int exponent, AdditionalArgs... additional_args) noexcept
1777 {
1778 ReturnType ret_value = {};
1779 IntervalType interval_type{additional_args...};
1780
1781
1782 const int minus_k = log::floor_log10_pow2_minus_log10_4_over_3(exponent);
1783 const int beta = exponent + log::floor_log2_pow10(-minus_k);
1784
1785
1786 const auto cache = CachePolicy::template get_cache<format>(-minus_k);
1787
1788 auto xi = compute_left_endpoint_for_shorter_interval_case(cache, beta);
1789 auto zi = compute_right_endpoint_for_shorter_interval_case(cache, beta);
1790
1791
1792
1793 if (!interval_type.include_right_endpoint() && is_right_endpoint_integer_shorter_interval(exponent))
1794 {
1795 --zi;
1796 }
1797
1798
1799 if (!interval_type.include_left_endpoint() || !is_left_endpoint_integer_shorter_interval(exponent))
1800 {
1801 ++xi;
1802 }
1803
1804
1805 ret_value.significand = zi / 10;
1806
1807
1808 if (ret_value.significand * 10 >= xi)
1809 {
1810 ret_value.exponent = minus_k + 1;
1811 TrailingZeroPolicy::template on_trailing_zeros<impl>(ret_value);
1812 return ret_value;
1813 }
1814
1815
1816 TrailingZeroPolicy::template no_trailing_zeros<impl>(ret_value);
1817 ret_value.significand = compute_round_up_for_shorter_interval_case(cache, beta);
1818 ret_value.exponent = minus_k;
1819
1820
1821 if (BinaryToDecimalRoundingPolicy::prefer_round_down(ret_value) &&
1822 exponent >= shorter_interval_tie_lower_threshold &&
1823 exponent <= shorter_interval_tie_upper_threshold)
1824 {
1825 --ret_value.significand;
1826 }
1827 else if (ret_value.significand < xi)
1828 {
1829 ++ret_value.significand;
1830 }
1831
1832 return ret_value;
1833 }
1834
1835 #if defined(__GNUC__) && (__GNUC__ < 5) && !defined(__clang__)
1836 # pragma GCC diagnostic pop
1837 #endif
1838
1839 template <class ReturnType, class TrailingZeroPolicy, class CachePolicy>
1840 BOOST_CHARCONV_SAFEBUFFERS static ReturnType compute_left_closed_directed(carrier_uint const two_fc, int exponent) noexcept
1841 {
1842
1843
1844
1845
1846 ReturnType ret_value;
1847
1848
1849 const int minus_k = log::floor_log10_pow2(exponent) - kappa;
1850 const auto cache = CachePolicy::template get_cache<format>(-minus_k);
1851 const int beta = exponent + log::floor_log2_pow10(-minus_k);
1852
1853
1854
1855 const auto deltai = compute_delta(cache, beta);
1856
1857 const auto x_res = compute_mul(two_fc << beta, cache);
1858 auto xi = x_res.result;
1859 auto is_x_integer = x_res.is_integer;
1860
1861
1862
1863
1864
1865
1866
1867 BOOST_IF_CONSTEXPR (std::is_same<format, ieee754_binary32>::value)
1868 {
1869 if (exponent <= -80)
1870 {
1871 is_x_integer = false;
1872 }
1873 }
1874
1875 if (!is_x_integer)
1876 {
1877 ++xi;
1878 }
1879
1880
1881
1882
1883
1884 BOOST_CXX14_CONSTEXPR auto big_divisor = compute_power(std::uint32_t(10), kappa + 1);
1885
1886
1887
1888
1889 #ifdef BOOST_NO_CXX14_CONSTEXPR
1890 ret_value.significand = div::divide_by_pow10<carrier_uint>(kappa + 1, (carrier_uint(1) << (significand_bits + 1)) * big_divisor - 1, xi);
1891 #else
1892 ret_value.significand = div::divide_by_pow10<kappa + 1, carrier_uint, (carrier_uint(1) << (significand_bits + 1)) * big_divisor - 1>(xi);
1893 #endif
1894
1895 auto r = std::uint32_t(xi - big_divisor * ret_value.significand);
1896
1897 if (r != 0)
1898 {
1899 ++ret_value.significand;
1900 r = big_divisor - r;
1901 }
1902
1903 if (r > deltai)
1904 {
1905 goto small_divisor_case_label;
1906 }
1907 else if (r == deltai)
1908 {
1909
1910
1911
1912
1913
1914
1915
1916
1917 const auto z_res = compute_mul_parity(two_fc + 2, cache, beta);
1918 if (z_res.parity || z_res.is_integer)
1919 {
1920 goto small_divisor_case_label;
1921 }
1922 }
1923
1924
1925 ret_value.exponent = minus_k + kappa + 1;
1926 TrailingZeroPolicy::template on_trailing_zeros<impl>(ret_value);
1927 return ret_value;
1928
1929
1930
1931
1932
1933
1934 small_divisor_case_label:
1935 ret_value.significand *= 10;
1936 ret_value.significand -= div::small_division_by_pow10<kappa>(r);
1937 ret_value.exponent = minus_k + kappa;
1938 TrailingZeroPolicy::template no_trailing_zeros<impl>(ret_value);
1939 return ret_value;
1940 }
1941
1942 template <typename ReturnType, typename TrailingZeroPolicy, typename CachePolicy>
1943 BOOST_CHARCONV_SAFEBUFFERS static ReturnType compute_right_closed_directed(carrier_uint const two_fc, const int exponent, bool shorter_interval) noexcept
1944 {
1945
1946
1947
1948
1949 ReturnType ret_value;
1950
1951
1952 const int minus_k = log::floor_log10_pow2(exponent - (shorter_interval ? 1 : 0)) - kappa;
1953 const auto cache = CachePolicy::template get_cache<format>(-minus_k);
1954 const int beta = exponent + log::floor_log2_pow10(-minus_k);
1955
1956
1957
1958 const auto deltai = shorter_interval ? compute_delta(cache, beta - 1) : compute_delta(cache, beta);
1959 carrier_uint const zi = compute_mul(two_fc << beta, cache).result;
1960
1961
1962
1963
1964
1965
1966 BOOST_CXX14_CONSTEXPR auto big_divisor = compute_power(std::uint32_t(10), kappa + 1);
1967
1968
1969
1970 #ifdef BOOST_NO_CXX14_CONSTEXPR
1971 ret_value.significand = div::divide_by_pow10<carrier_uint>(kappa + 1, (carrier_uint(1) << (significand_bits + 1)) * big_divisor - 1, zi);
1972 #else
1973 ret_value.significand = div::divide_by_pow10<kappa + 1, carrier_uint, (carrier_uint(1) << (significand_bits + 1)) * big_divisor - 1>(zi);
1974 #endif
1975
1976 const auto r = std::uint32_t(zi - big_divisor * ret_value.significand);
1977
1978 if (r > deltai)
1979 {
1980 goto small_divisor_case_label;
1981 }
1982 else if (r == deltai)
1983 {
1984
1985 if (!compute_mul_parity(two_fc - (shorter_interval ? 1 : 2), cache, beta).parity)
1986 {
1987 goto small_divisor_case_label;
1988 }
1989 }
1990
1991
1992 ret_value.exponent = minus_k + kappa + 1;
1993 TrailingZeroPolicy::template on_trailing_zeros<impl>(ret_value);
1994 return ret_value;
1995
1996
1997
1998
1999
2000
2001 small_divisor_case_label:
2002 ret_value.significand *= 10;
2003 ret_value.significand += div::small_division_by_pow10<kappa>(r);
2004 ret_value.exponent = minus_k + kappa;
2005 TrailingZeroPolicy::template no_trailing_zeros<impl>(ret_value);
2006
2007 return ret_value;
2008 }
2009
2010
2011 BOOST_FORCEINLINE static int remove_trailing_zeros(carrier_uint& n) noexcept
2012 {
2013 if (n == 0)
2014 {
2015 return 0;
2016 }
2017
2018 BOOST_IF_CONSTEXPR (std::is_same<format, ieee754_binary32>::value)
2019 {
2020 constexpr auto mod_inv_5 = UINT32_C(0xcccccccd);
2021 constexpr auto mod_inv_25 = mod_inv_5 * mod_inv_5;
2022
2023 int s = 0;
2024 while (true)
2025 {
2026 auto q = boost::core::rotr(n * mod_inv_25, 2);
2027 if (q <= (std::numeric_limits<std::uint32_t>::max)() / 100)
2028 {
2029 n = q;
2030 s += 2;
2031 }
2032 else
2033 {
2034 break;
2035 }
2036 }
2037 auto q = boost::core::rotr(n * mod_inv_5, 1);
2038 if (q <= (std::numeric_limits<std::uint32_t>::max)() / 10)
2039 {
2040 n = q;
2041 s |= 1;
2042 }
2043
2044 return s;
2045 }
2046 else
2047 {
2048
2049
2050
2051
2052
2053
2054
2055
2056 constexpr auto magic_number = UINT64_C(12379400392853802749);
2057 auto nm = umul128(n, magic_number);
2058
2059
2060 if ((nm.high & ((std::uint64_t(1) << (90 - 64)) - 1)) == 0 &&
2061 nm.low < magic_number) {
2062
2063 auto n32 = static_cast<std::uint32_t>(nm.high >> (90 - 64));
2064
2065 constexpr auto mod_inv_5 = UINT32_C(0xcccccccd);
2066 constexpr auto mod_inv_25 = mod_inv_5 * mod_inv_5;
2067
2068 int s = 8;
2069 while (true)
2070 {
2071 auto q = boost::core::rotr(n32 * mod_inv_25, 2);
2072 if (q <= (std::numeric_limits<std::uint32_t>::max)() / 100)
2073 {
2074 n32 = q;
2075 s += 2;
2076 }
2077 else
2078 {
2079 break;
2080 }
2081 }
2082
2083 auto q = boost::core::rotr(n32 * mod_inv_5, 1);
2084 if (q <= (std::numeric_limits<std::uint32_t>::max)() / 10)
2085 {
2086 n32 = q;
2087 s |= 1;
2088 }
2089
2090 n = n32;
2091 return s;
2092 }
2093
2094
2095 constexpr auto mod_inv_5 = UINT64_C(0xcccccccccccccccd);
2096 constexpr auto mod_inv_25 = mod_inv_5 * mod_inv_5;
2097
2098 int s = 0;
2099 while (true)
2100 {
2101 auto q = static_cast<carrier_uint>(boost::core::rotr(n * mod_inv_25, 2));
2102 if (q <= (std::numeric_limits<std::uint64_t>::max)() / 100)
2103 {
2104 n = q;
2105 s += 2;
2106 }
2107 else
2108 {
2109 break;
2110 }
2111 }
2112
2113 auto q = static_cast<carrier_uint>(boost::core::rotr(n * mod_inv_5, 1));
2114 if (q <= (std::numeric_limits<std::uint64_t>::max)() / 10)
2115 {
2116 n = q;
2117 s |= 1;
2118 }
2119
2120 return s;
2121 }
2122 }
2123
2124 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary32>::value, bool>::type = true>
2125 static compute_mul_result compute_mul(carrier_uint u, cache_entry_type const& cache) noexcept
2126 {
2127 auto r = umul96_upper64(u, cache);
2128 return {carrier_uint(r >> 32), carrier_uint(r) == 0};
2129 }
2130
2131 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary64>::value, bool>::type = true>
2132 static compute_mul_result compute_mul(carrier_uint u, cache_entry_type const& cache) noexcept
2133 {
2134 auto r = umul192_upper128(u, cache);
2135 return {r.high, r.low == 0};
2136 }
2137
2138 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary32>::value, bool>::type = true>
2139 static constexpr std::uint32_t compute_delta(cache_entry_type const& cache,
2140 int beta) noexcept
2141 {
2142 return std::uint32_t(cache >> (cache_bits - 1 - beta));
2143 }
2144
2145 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary64>::value, bool>::type = true>
2146 static constexpr std::uint32_t compute_delta(cache_entry_type const& cache,
2147 int beta) noexcept
2148 {
2149 return std::uint32_t(cache.high >> (carrier_bits - 1 - beta));
2150 }
2151
2152 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary32>::value, bool>::type = true>
2153 static compute_mul_parity_result compute_mul_parity(carrier_uint two_f,
2154 cache_entry_type const& cache,
2155 int beta) noexcept
2156 {
2157 auto r = umul96_lower64(two_f, cache);
2158 return {((r >> (64 - beta)) & 1) != 0, std::uint32_t(r >> (32 - beta)) == 0};
2159 }
2160
2161 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary64>::value, bool>::type = true>
2162 static compute_mul_parity_result compute_mul_parity(carrier_uint two_f,
2163 cache_entry_type const& cache,
2164 int beta) noexcept
2165 {
2166 auto r = umul192_lower128(two_f, cache);
2167 return {((r.high >> (64 - beta)) & 1) != 0, ((r.high << beta) | (r.low >> (64 - beta))) == 0};
2168 }
2169
2170 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary32>::value, bool>::type = true>
2171 static constexpr carrier_uint compute_left_endpoint_for_shorter_interval_case(cache_entry_type const& cache, int beta) noexcept
2172 {
2173 return carrier_uint((cache - (cache >> (significand_bits + 2))) >> (cache_bits - significand_bits - 1 - beta));
2174 }
2175
2176 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary64>::value, bool>::type = true>
2177 static constexpr carrier_uint compute_left_endpoint_for_shorter_interval_case(cache_entry_type const& cache, int beta) noexcept
2178 {
2179 return (cache.high - (cache.high >> (significand_bits + 2))) >> (carrier_bits - significand_bits - 1 - beta);
2180 }
2181
2182 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary32>::value, bool>::type = true>
2183 static constexpr carrier_uint compute_right_endpoint_for_shorter_interval_case(cache_entry_type const& cache, int beta) noexcept
2184 {
2185 return carrier_uint((cache + (cache >> (significand_bits + 1))) >> (cache_bits - significand_bits - 1 - beta));
2186 }
2187
2188 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary64>::value, bool>::type = true>
2189 static constexpr carrier_uint compute_right_endpoint_for_shorter_interval_case(cache_entry_type const& cache, int beta) noexcept
2190 {
2191 return (cache.high + (cache.high >> (significand_bits + 1))) >> (carrier_bits - significand_bits - 1 - beta);
2192 }
2193
2194 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary32>::value, bool>::type = true>
2195 static constexpr carrier_uint compute_round_up_for_shorter_interval_case(cache_entry_type const& cache, int beta) noexcept
2196 {
2197 return (carrier_uint(cache >> (cache_bits - significand_bits - 2 - beta)) + 1) / 2;
2198 }
2199
2200 template <typename local_format = format, typename std::enable_if<std::is_same<local_format, ieee754_binary64>::value, bool>::type = true>
2201 static constexpr carrier_uint compute_round_up_for_shorter_interval_case(cache_entry_type const& cache, int beta) noexcept
2202 {
2203 return ((cache.high >> (carrier_bits - significand_bits - 2 - beta)) + 1) / 2;
2204 }
2205
2206 static constexpr bool is_right_endpoint_integer_shorter_interval(int exponent) noexcept
2207 {
2208 return exponent >= case_shorter_interval_right_endpoint_lower_threshold &&
2209 exponent <= case_shorter_interval_right_endpoint_upper_threshold;
2210 }
2211
2212 static constexpr bool is_left_endpoint_integer_shorter_interval(int exponent) noexcept
2213 {
2214 return exponent >= case_shorter_interval_left_endpoint_lower_threshold &&
2215 exponent <= case_shorter_interval_left_endpoint_upper_threshold;
2216 }
2217 };
2218
2219
2220
2221
2222
2223
2224 namespace policy_impl {
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239 enum class policy_found_info
2240 {
2241 not_found,
2242 unique,
2243 repeated
2244 };
2245
2246 template <typename Policy, policy_found_info info>
2247 struct found_policy_pair
2248 {
2249 using policy = Policy;
2250 static constexpr auto found_info = info;
2251 };
2252
2253 template <typename Base, typename DefaultPolicy>
2254 struct base_default_pair
2255 {
2256 using base = Base;
2257
2258 template <class FoundPolicyInfo>
2259 static constexpr FoundPolicyInfo get_policy_impl(FoundPolicyInfo)
2260 {
2261 return {};
2262 }
2263
2264 template <typename FoundPolicyInfo, typename FirstPolicy, typename... RemainingPolicies,
2265 typename std::enable_if<std::is_base_of<Base, FirstPolicy>::value && (FoundPolicyInfo::found_info == policy_found_info::not_found), bool>::type = true>
2266 static constexpr auto get_policy_impl(FoundPolicyInfo, FirstPolicy, RemainingPolicies... remainings) noexcept -> found_policy_pair<FirstPolicy, policy_found_info::unique>
2267 {
2268 return get_policy_impl(found_policy_pair<FirstPolicy, policy_found_info::unique>{}, remainings...);
2269 }
2270
2271 template <typename FoundPolicyInfo, typename FirstPolicy, typename... RemainingPolicies,
2272 typename std::enable_if<std::is_base_of<Base, FirstPolicy>::value && !(FoundPolicyInfo::found_info == policy_found_info::not_found), bool>::type = true>
2273 static constexpr auto get_policy_impl(FoundPolicyInfo, FirstPolicy, RemainingPolicies... remainings) noexcept -> found_policy_pair<FirstPolicy, policy_found_info::repeated>
2274 {
2275 return get_policy_impl(found_policy_pair<FirstPolicy, policy_found_info::repeated>{}, remainings...);
2276 }
2277
2278 template <typename FoundPolicyInfo, typename FirstPolicy, typename... RemainingPolicies,
2279 typename std::enable_if<!std::is_base_of<Base, FirstPolicy>::value, bool>::type = true>
2280 static constexpr auto get_policy_impl(FoundPolicyInfo, FirstPolicy, RemainingPolicies... remainings) noexcept -> found_policy_pair<FirstPolicy, FoundPolicyInfo::found_info>
2281 {
2282 return get_policy_impl(FoundPolicyInfo{}, remainings...);
2283 }
2284
2285 template <typename... Policies>
2286 static constexpr auto get_policy(Policies... policies) -> found_policy_pair<DefaultPolicy, policy_found_info::not_found>
2287 {
2288 return get_policy_impl(found_policy_pair<DefaultPolicy, policy_found_info::not_found>{}, policies...);
2289 }
2290 };
2291
2292 template <typename... BaseDefaultPairs>
2293 struct base_default_pair_list {};
2294
2295
2296 template <typename Policy>
2297 constexpr bool check_policy_validity(Policy, base_default_pair_list<>)
2298 {
2299 return false;
2300 }
2301
2302 template <typename Policy, typename FirstBaseDefaultPair, typename... RemainingBaseDefaultPairs>
2303 constexpr bool check_policy_validity(Policy, base_default_pair_list<FirstBaseDefaultPair, RemainingBaseDefaultPairs...>)
2304 {
2305 return std::is_base_of<typename FirstBaseDefaultPair::base, Policy>::value ||
2306 check_policy_validity(Policy{}, base_default_pair_list<RemainingBaseDefaultPairs...>{});
2307 }
2308
2309 template <typename BaseDefaultPairList>
2310 constexpr bool check_policy_list_validity(BaseDefaultPairList)
2311 {
2312 return true;
2313 }
2314
2315 template <typename BaseDefaultPairList, typename FirstPolicy, typename... RemainingPolicies>
2316 constexpr bool check_policy_list_validity(BaseDefaultPairList, FirstPolicy, RemainingPolicies... remaining_policies)
2317 {
2318 return check_policy_validity(FirstPolicy{}, BaseDefaultPairList{}) &&
2319 check_policy_list_validity(BaseDefaultPairList{}, remaining_policies...);
2320 }
2321
2322
2323 template <bool repeated_, typename... FoundPolicyPairs>
2324 struct found_policy_pair_list
2325 {
2326 static constexpr bool repeated = repeated_;
2327 };
2328
2329 template <typename... Policies>
2330 struct policy_holder : Policies... {};
2331
2332 #ifndef BOOST_CHARCONV_NO_CXX14_RETURN_TYPE_DEDUCTION
2333
2334 template <bool repeated, typename... FoundPolicyPairs, typename... Policies>
2335 constexpr auto make_policy_holder_impl(base_default_pair_list<>, found_policy_pair_list<repeated, FoundPolicyPairs...>, Policies...)
2336 -> found_policy_pair_list<repeated, FoundPolicyPairs...>
2337 {
2338 return found_policy_pair_list<repeated, FoundPolicyPairs...>{};
2339 }
2340
2341 template <typename FirstBaseDefaultPair, typename... RemainingBaseDefaultPairs, bool repeated,
2342 typename... FoundPolicyPairs, typename... Policies>
2343 constexpr auto make_policy_holder_impl(base_default_pair_list<FirstBaseDefaultPair, RemainingBaseDefaultPairs...>,
2344 found_policy_pair_list<repeated, FoundPolicyPairs...>, Policies... policies)
2345 {
2346 using new_found_policy_pair = decltype(FirstBaseDefaultPair::get_policy(policies...));
2347
2348 return make_policy_holder_impl(base_default_pair_list<RemainingBaseDefaultPairs...>{},
2349 found_policy_pair_list < repeated || new_found_policy_pair::found_info == policy_found_info::repeated,
2350 new_found_policy_pair, FoundPolicyPairs... > {}, policies...);
2351 }
2352
2353 template <bool repeated, typename... RawPolicies>
2354 constexpr auto convert_to_policy_holder(found_policy_pair_list<repeated>, RawPolicies...) -> policy_holder<RawPolicies...>
2355 {
2356 return policy_holder<RawPolicies...>{};
2357 }
2358
2359 template <bool repeated, typename FirstFoundPolicyPair, typename... RemainingFoundPolicyPairs, typename... RawPolicies>
2360 constexpr auto convert_to_policy_holder(found_policy_pair_list<repeated, FirstFoundPolicyPair, RemainingFoundPolicyPairs...>,
2361 RawPolicies... policies)
2362 {
2363 return convert_to_policy_holder(found_policy_pair_list<repeated, RemainingFoundPolicyPairs...>{}, typename FirstFoundPolicyPair::policy{}, policies...);
2364 }
2365
2366 template <typename BaseDefaultPairList, typename... Policies>
2367 constexpr auto make_policy_holder(BaseDefaultPairList, Policies... policies)
2368 {
2369 static_assert(check_policy_list_validity(BaseDefaultPairList{}, Policies{}...),
2370 "jkj::dragonbox: an invalid policy is specified");
2371
2372 using policy_pair_list = decltype(make_policy_holder_impl(
2373 BaseDefaultPairList{}, found_policy_pair_list<false>{}, policies...));
2374
2375 static_assert(!policy_pair_list::repeated,
2376 "jkj::dragonbox: each policy should be specified at most once");
2377
2378 return convert_to_policy_holder(policy_pair_list{});
2379 }
2380 #endif
2381 }
2382
2383
2384
2385
2386 #ifdef BOOST_MSVC
2387 # pragma warning(push)
2388 # pragma warning(disable: 4100)
2389 # pragma warning(disable: 4189)
2390 #endif
2391
2392 template <typename Float, typename FloatTraits = dragonbox_float_traits<Float>, typename... Policies>
2393 BOOST_FORCEINLINE BOOST_CHARCONV_SAFEBUFFERS auto
2394 to_decimal(dragonbox_signed_significand_bits<Float, FloatTraits> dragonbox_signed_significand_bits,
2395 unsigned int exponent_bits, BOOST_ATTRIBUTE_UNUSED Policies... policies) noexcept
2396 #ifdef BOOST_CHARCONV_NO_CXX14_RETURN_TYPE_DEDUCTION
2397 -> decimal_fp<typename FloatTraits::carrier_uint, true, false>
2398 #endif
2399 {
2400
2401 using namespace policy_impl;
2402
2403 #ifdef BOOST_CHARCONV_NO_CXX14_RETURN_TYPE_DEDUCTION
2404
2405 using policy_holder = policy_holder<decimal_to_binary_rounding::nearest_to_even, binary_to_decimal_rounding::to_even, cache::full, sign::return_sign, trailing_zero::remove>;
2406
2407 #else
2408
2409 using policy_holder = decltype(make_policy_holder(
2410 base_default_pair_list<base_default_pair<sign::base, sign::return_sign>,
2411 base_default_pair<trailing_zero::base, trailing_zero::remove>,
2412 base_default_pair<decimal_to_binary_rounding::base,
2413 decimal_to_binary_rounding::nearest_to_even>,
2414 base_default_pair<binary_to_decimal_rounding::base,
2415 binary_to_decimal_rounding::to_even>,
2416 base_default_pair<cache::base, cache::full>>{},
2417 policies...));
2418
2419 #endif
2420
2421 using return_type = decimal_fp<typename FloatTraits::carrier_uint, policy_holder::return_has_sign, policy_holder::report_trailing_zeros>;
2422
2423 return_type ret = policy_holder::template delegate<return_type>(dragonbox_signed_significand_bits,
2424 [exponent_bits, dragonbox_signed_significand_bits](policy_impl::decimal_to_binary_rounding::nearest_to_even interval_type_provider) {
2425 using format = typename FloatTraits::format;
2426 constexpr auto tag = decltype(interval_type_provider)::tag;
2427
2428 auto two_fc = dragonbox_signed_significand_bits.remove_sign_bit_and_shift();
2429 auto exponent = int(exponent_bits);
2430
2431 BOOST_IF_CONSTEXPR (tag == decimal_to_binary_rounding::tag_t::to_nearest) {
2432
2433 if (exponent != 0) {
2434 exponent += format::exponent_bias - format::significand_bits;
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462 static_assert(std::is_same<format, ieee754_binary32>::value ||
2463 std::is_same<format, ieee754_binary64>::value, "Format must be IEEE754 binary 32 or 64");
2464
2465 if (two_fc == 0) {
2466 return decltype(interval_type_provider)::template invoke_shorter_interval_case<return_type>(
2467 dragonbox_signed_significand_bits, [exponent]() {
2468 return detail::impl<Float, FloatTraits>::
2469 template compute_nearest_shorter<
2470 return_type,
2471 typename decltype(interval_type_provider)::
2472 shorter_interval_type,
2473 typename policy_holder::trailing_zero_policy,
2474 typename policy_holder::
2475 binary_to_decimal_rounding_policy,
2476 typename policy_holder::cache_policy>(
2477 exponent);
2478 });
2479 }
2480
2481 two_fc |= (decltype(two_fc)(1) << (format::significand_bits + 1));
2482 }
2483
2484 else {
2485 exponent = format::min_exponent - format::significand_bits;
2486 }
2487
2488 return decltype(interval_type_provider)::template invoke_normal_interval_case<return_type>(
2489 dragonbox_signed_significand_bits, [two_fc, exponent](bool additional_args) {
2490 return detail::impl<Float, FloatTraits>::
2491 template compute_nearest_normal<
2492 return_type,
2493 typename decltype(interval_type_provider)::normal_interval_type,
2494 typename policy_holder::trailing_zero_policy,
2495 typename policy_holder::binary_to_decimal_rounding_policy,
2496 typename policy_holder::cache_policy>(two_fc, exponent, additional_args);
2497 });
2498 }
2499 else BOOST_IF_CONSTEXPR (tag == decimal_to_binary_rounding::tag_t::left_closed_directed)
2500 {
2501
2502 if (exponent != 0) {
2503 exponent += format::exponent_bias - format::significand_bits;
2504 two_fc |= (decltype(two_fc)(1) << (format::significand_bits + 1));
2505 }
2506
2507 else {
2508 exponent = format::min_exponent - format::significand_bits;
2509 }
2510
2511 return detail::impl<Float>::template compute_left_closed_directed<
2512 return_type, typename policy_holder::trailing_zero_policy,
2513 typename policy_holder::cache_policy>(two_fc, exponent);
2514 }
2515 else
2516 {
2517
2518
2519
2520 bool shorter_interval = false;
2521
2522
2523 if (exponent != 0) {
2524 if (two_fc == 0 && exponent != 1) {
2525 shorter_interval = true;
2526 }
2527 exponent += format::exponent_bias - format::significand_bits;
2528 two_fc |= (decltype(two_fc)(1) << (format::significand_bits + 1));
2529 }
2530
2531 else {
2532 exponent = format::min_exponent - format::significand_bits;
2533 }
2534
2535 return detail::impl<Float>::template compute_right_closed_directed<
2536 return_type, typename policy_holder::trailing_zero_policy,
2537 typename policy_holder::cache_policy>(two_fc, exponent, shorter_interval);
2538 }
2539 });
2540
2541 policy_holder::handle_sign(dragonbox_signed_significand_bits, ret);
2542 return ret;
2543 }
2544
2545 #ifdef BOOST_MSVC
2546 # pragma warning(pop)
2547 #endif
2548
2549 template <typename Float, typename FloatTraits = dragonbox_float_traits<Float>, typename... Policies>
2550 BOOST_FORCEINLINE BOOST_CHARCONV_SAFEBUFFERS auto to_decimal(Float x, Policies... policies) noexcept
2551 #ifdef BOOST_CHARCONV_NO_CXX14_RETURN_TYPE_DEDUCTION
2552 -> decimal_fp<typename FloatTraits::carrier_uint, true, false>
2553 #endif
2554 {
2555 const auto br = dragonbox_float_bits<Float, FloatTraits>(x);
2556 const auto exponent_bits = br.extract_exponent_bits();
2557 const auto s = br.remove_exponent_bits(exponent_bits);
2558
2559 return to_decimal<Float, FloatTraits>(s, exponent_bits, policies...);
2560 }
2561
2562 namespace to_chars_detail {
2563 template <class Float, class FloatTraits>
2564 extern to_chars_result dragon_box_print_chars(typename FloatTraits::carrier_uint significand, int exponent, char* first, char* last, chars_format fmt) noexcept;
2565
2566
2567 template <class PolicyHolder, class Float, class FloatTraits>
2568 to_chars_result to_chars_n_impl(dragonbox_float_bits<Float, FloatTraits> br, char* first, char* last, chars_format fmt) noexcept
2569 {
2570 const auto exponent_bits = br.extract_exponent_bits();
2571 const auto s = br.remove_exponent_bits(exponent_bits);
2572
2573 auto buffer = first;
2574 const auto buffer_size = last - first;
2575
2576 if (br.is_finite(exponent_bits))
2577 {
2578 if (s.is_negative())
2579 {
2580 *buffer = '-';
2581 ++buffer;
2582 }
2583 if (br.is_nonzero())
2584 {
2585 auto result = to_decimal<Float, FloatTraits>(
2586 s, exponent_bits, policy::sign::ignore, policy::trailing_zero::ignore,
2587 typename PolicyHolder::decimal_to_binary_rounding_policy{},
2588 typename PolicyHolder::binary_to_decimal_rounding_policy{},
2589 typename PolicyHolder::cache_policy{});
2590 return to_chars_detail::dragon_box_print_chars<Float, FloatTraits>(result.significand, result.exponent, buffer, last, fmt);
2591 }
2592 else
2593 {
2594 if (fmt != chars_format::scientific)
2595 {
2596 std::memcpy(buffer, "0", 1);
2597 return {buffer + 1, std::errc()};
2598 }
2599
2600 if (buffer_size >= 5)
2601 {
2602 std::memcpy(buffer, "0e+00", 5);
2603 return {buffer + 5, std::errc()};
2604 }
2605 else
2606 {
2607 return {last, std::errc::value_too_large};
2608 }
2609 }
2610 }
2611 else
2612 {
2613 bool is_negative = false;
2614 if (s.is_negative())
2615 {
2616 *buffer = '-';
2617 ++buffer;
2618 is_negative = true;
2619 }
2620
2621 if (s.has_all_zero_significand_bits())
2622 {
2623 if (buffer_size >= 3 + static_cast<std::ptrdiff_t>(is_negative))
2624 {
2625 std::memcpy(buffer, "inf", 3);
2626 return {buffer + 3, std::errc()};
2627 }
2628 else
2629 {
2630 return {last, std::errc::value_too_large};
2631 }
2632 }
2633 else
2634 {
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644 int nan_type;
2645 BOOST_IF_CONSTEXPR (std::is_same<typename FloatTraits::format, ieee754_binary32>::value)
2646 {
2647 if (br.extract_significand_bits() == UINT32_C(4194304))
2648 {
2649 nan_type = 1;
2650 }
2651 else
2652 {
2653 nan_type = 0;
2654 }
2655 }
2656 else
2657 {
2658 if (br.extract_significand_bits() == UINT64_C(2251799813685248))
2659 {
2660 nan_type = 1;
2661 }
2662 else
2663 {
2664 nan_type = 0;
2665 }
2666 }
2667
2668 if (nan_type == 1)
2669 {
2670 if (!s.is_negative())
2671 {
2672 if (buffer_size >= 3 + static_cast<std::ptrdiff_t>(is_negative))
2673 {
2674 std::memcpy(buffer, "nan", 3);
2675 return {buffer + 3, std::errc()};
2676 }
2677 else
2678 {
2679 return {last, std::errc::value_too_large};
2680 }
2681 }
2682 else
2683 {
2684 if (buffer_size >= 8 + static_cast<std::ptrdiff_t>(is_negative))
2685 {
2686 std::memcpy(buffer, "nan(ind)", 8);
2687 return {buffer + 8, std::errc()};
2688 }
2689 else
2690 {
2691 return {last, std::errc::value_too_large};
2692 }
2693 }
2694 }
2695 else
2696 {
2697 if (buffer_size >= 9 + static_cast<std::ptrdiff_t>(is_negative))
2698 {
2699 std::memcpy(buffer, "nan(snan)", 9);
2700 return {buffer + 9, std::errc()};
2701 }
2702 else
2703 {
2704 return {last, std::errc::value_too_large};
2705 }
2706 }
2707 }
2708 }
2709 }
2710 }
2711
2712
2713 template <typename Float, typename FloatTraits = dragonbox_float_traits<Float>, typename... Policies>
2714 to_chars_result to_chars_n(Float x, char* first, char* last, chars_format fmt, BOOST_ATTRIBUTE_UNUSED Policies... policies) noexcept
2715 {
2716 using namespace policy_impl;
2717
2718 #ifdef BOOST_CHARCONV_NO_CXX14_RETURN_TYPE_DEDUCTION
2719
2720 using policy_holder = policy_holder<decimal_to_binary_rounding::nearest_to_even, binary_to_decimal_rounding::to_even, cache::full, sign::return_sign, trailing_zero::remove>;
2721
2722 #else
2723
2724 using policy_holder = decltype(make_policy_holder(
2725 base_default_pair_list<base_default_pair<sign::base, sign::return_sign>,
2726 base_default_pair<trailing_zero::base, trailing_zero::remove>,
2727 base_default_pair<decimal_to_binary_rounding::base,
2728 decimal_to_binary_rounding::nearest_to_even>,
2729 base_default_pair<binary_to_decimal_rounding::base,
2730 binary_to_decimal_rounding::to_even>,
2731 base_default_pair<cache::base, cache::full>>{},
2732 policies...));
2733
2734 #endif
2735
2736 return to_chars_detail::to_chars_n_impl<policy_holder>(dragonbox_float_bits<Float, FloatTraits>(x), first, last, fmt);
2737 }
2738
2739
2740 template <typename Float, typename FloatTraits = dragonbox_float_traits<Float>, typename... Policies>
2741 to_chars_result dragonbox_to_chars(Float x, char* first, char* last, chars_format fmt, Policies... policies) noexcept
2742 {
2743 return to_chars_n<Float, FloatTraits>(x, first, last, fmt, policies...);
2744 }
2745
2746 }}}
2747
2748 #ifdef BOOST_MSVC
2749 # pragma warning(pop)
2750 #endif
2751
2752 #endif