On Thu, Oct 9, 2025 at 4:44 PM Matt Borland <matt@mattborland.com> wrote:
We have, and if I remember correctly several people brought it up last review. The C++ developer survey for 2025 [1] shows we probably wouldn't alienate too many people with the change. Right now I don't think removing the IF_CONSTEXPR macro, _v, etc. is sufficiently compelling to change to C++17 and refactor. C++20 would be more beneficial, but the adoption rate just isn't there right now.
You could also nuke the macros for when function return type is different, since if constexpr "understands" that, if does not. In any case your choice. :) Another question about documentation, I think this may have been asked during last review but I am not sure. IIRC fast types do not support subnormal numbers, e.g. this prints different values: std::print("{:.20e}\n", std::numeric_limits<decimal32_t>::denorm_min()); std::print("{:.20e}\n", std::numeric_limits<decimal_fast32_t>::denorm_min()); but documentation claims they offer same results as non fast ones. Is this documentation issue or you think documentation is correct? I would say that the fact that value X in non fast can be divided in and produce subnormal result(greater than 0) is quite different from getting rounding to 0 for fast type. Now that we have seen the three basic types as specified in IEEE-754 there are three additional adjacent types: decimal_fast32_t, decimal_fast64_t, and decimal_fast128_t. These types yield identical computational results but with faster performance. Another question about digits count, could this be implemented without the checks on estimated_digits, i.e. by making the array larger or some trick like that to avoid checking estimated_digits < 10 and estimated_digits > 1? I do not claim I benchmarked this, but I know people usually try to replace branches in code like this with "clever" array access. constexpr auto num_digits(T init_x) noexcept -> int { // Use the most significant bit position to approximate log10 // log10(x) ~= log2(x) / log2(10) ~= log2(x) / 3.32 const auto x {static_cast<std::uint32_t>(init_x)}; const auto msb {32 - int128::detail::impl::countl_impl(x)}; // Approximate log10 const auto estimated_digits {(msb * 1000) / 3322 + 1}; // 1000/3322 ~= 1/log2(10) if (estimated_digits < 10 && x >= impl::powers_of_10_u32[estimated_digits]) { return estimated_digits + 1; } if (estimated_digits > 1 && x < impl::powers_of_10_u32[estimated_digits - 1]) { return estimated_digits - 1; } return estimated_digits; }