JKJ_FORCEINLINE JKJ_SAFEBUFFERS auto to_decimal()

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;
}