in include/ylt/util/dragonbox.h [2891:3040]
JKJ_FORCEINLINE JKJ_SAFEBUFFERS auto to_decimal(
signed_significand_bits<Float, FloatTraits> signed_significand_bits,
unsigned int exponent_bits, Policies... policies) noexcept {
// Build policy holder type.
using namespace detail::policy_impl;
using policy_holder = decltype(make_policy_holder(
base_default_pair_list<
base_default_pair<sign::base, sign::return_sign>,
base_default_pair<trailing_zero::base, trailing_zero::remove>,
base_default_pair<decimal_to_binary_rounding::base,
decimal_to_binary_rounding::nearest_to_even>,
base_default_pair<binary_to_decimal_rounding::base,
binary_to_decimal_rounding::to_even>,
base_default_pair<cache::base, cache::full>>{},
policies...));
using return_type = decimal_fp<typename FloatTraits::carrier_uint,
policy_holder::return_has_sign,
policy_holder::report_trailing_zeros>;
return_type ret = policy_holder::delegate(
signed_significand_bits,
[exponent_bits, signed_significand_bits](auto interval_type_provider) {
using format = typename FloatTraits::format;
constexpr auto tag = decltype(interval_type_provider)::tag;
auto two_fc = signed_significand_bits.remove_sign_bit_and_shift();
auto exponent = int(exponent_bits);
if constexpr (tag == decimal_to_binary_rounding::tag_t::to_nearest) {
// Is the input a normal number?
if (exponent != 0) {
exponent += format::exponent_bias - format::significand_bits;
// Shorter interval case; proceed like Schubfach.
// One might think this condition is wrong, since when exponent_bits
// == 1 and two_fc == 0, the interval is actually regular. However,
// it turns out that this seemingly wrong condition is actually
// fine, because the end result is anyway the same.
//
// [binary32]
// (fc-1/2) * 2^e = 1.175'494'28... * 10^-38
// (fc-1/4) * 2^e = 1.175'494'31... * 10^-38
// fc * 2^e = 1.175'494'35... * 10^-38
// (fc+1/2) * 2^e = 1.175'494'42... * 10^-38
//
// Hence, shorter_interval_case will return 1.175'494'4 * 10^-38.
// 1.175'494'3 * 10^-38 is also a correct shortest representation
// that will be rejected if we assume shorter interval,
// but 1.175'494'4 * 10^-38 is closer to the true value so it
// doesn't matter.
//
// [binary64]
// (fc-1/2) * 2^e = 2.225'073'858'507'201'13... * 10^-308
// (fc-1/4) * 2^e = 2.225'073'858'507'201'25... * 10^-308
// fc * 2^e = 2.225'073'858'507'201'38... * 10^-308
// (fc+1/2) * 2^e = 2.225'073'858'507'201'63... * 10^-308
//
// Hence, shorter_interval_case will return 2.225'073'858'507'201'4
// * 10^-308. This is indeed of the shortest length, and it is the
// unique one closest to the true value among valid representations
// of the same length.
static_assert(std::is_same_v<format, ieee754_binary32> ||
std::is_same_v<format, ieee754_binary64>);
if (two_fc == 0) {
return decltype(interval_type_provider)::
invoke_shorter_interval_case(
signed_significand_bits,
[exponent](auto... additional_args) {
return detail::impl<Float, FloatTraits>::
template compute_nearest_shorter<
return_type,
typename decltype(interval_type_provider)::
shorter_interval_type,
typename policy_holder::trailing_zero_policy,
typename policy_holder::
binary_to_decimal_rounding_policy,
typename policy_holder::cache_policy>(
exponent, additional_args...);
});
}
two_fc |= (decltype(two_fc)(1) << (format::significand_bits + 1));
}
// Is the input a subnormal number?
else {
exponent = format::min_exponent - format::significand_bits;
}
return decltype(interval_type_provider)::invoke_normal_interval_case(
signed_significand_bits,
[two_fc, exponent](auto... additional_args) {
return detail::impl<Float, FloatTraits>::
template compute_nearest_normal<
return_type,
typename decltype(interval_type_provider)::
normal_interval_type,
typename policy_holder::trailing_zero_policy,
typename policy_holder::
binary_to_decimal_rounding_policy,
typename policy_holder::cache_policy>(
two_fc, exponent, additional_args...);
});
}
else if constexpr (tag == decimal_to_binary_rounding::tag_t::
left_closed_directed) {
// Is the input a normal number?
if (exponent != 0) {
exponent += format::exponent_bias - format::significand_bits;
two_fc |= (decltype(two_fc)(1) << (format::significand_bits + 1));
}
// Is the input a subnormal number?
else {
exponent = format::min_exponent - format::significand_bits;
}
return detail::impl<Float>::template compute_left_closed_directed<
return_type, typename policy_holder::trailing_zero_policy,
typename policy_holder::cache_policy>(two_fc, exponent);
}
else {
static_assert(
tag == decimal_to_binary_rounding::tag_t::right_closed_directed);
bool shorter_interval = false;
// Is the input a normal number?
if (exponent != 0) {
if (two_fc == 0 && exponent != 1) {
shorter_interval = true;
}
exponent += format::exponent_bias - format::significand_bits;
two_fc |= (decltype(two_fc)(1) << (format::significand_bits + 1));
}
// Is the input a subnormal number?
else {
exponent = format::min_exponent - format::significand_bits;
}
return detail::impl<Float>::template compute_right_closed_directed<
return_type, typename policy_holder::trailing_zero_policy,
typename policy_holder::cache_policy>(two_fc, exponent,
shorter_interval);
}
});
policy_holder::handle_sign(signed_significand_bits, ret);
return ret;
}