On Mon, Oct 13, 2025 at 6:35 PM Matt Borland <matt@mattborland.com> wrote:
The non-template variables for numbers::pi, log2e etc are all double so we went with decimal64_t for consistency [1]. pi_v<decimal128_t> is available in your case.
My intuition is that it is still a footgun. std:: can not magically make all compilers change long double to 64 or 80 bit, but you control Decimal code so I think making them 128 bit constants would be better. But to be honest I have not found any discussion of double vs long double in paper that proposed <numbers> header so I may be missing something. I presume narrower types will not be easily constructible from wider so making constants d128 will make code more verbose. But I am not sure being concise is worth the potential issues. I have question about hash: template <> struct hash<boost::decimal::decimal_fast128_t> { // Take the xor of the two words and hash that auto operator()(const boost::decimal::decimal_fast128_t& v) const noexcept -> std::size_t { boost::decimal::decimal128_t v_128 {v}; boost::int128::uint128_t bits; std::memcpy(&bits, &v_128, sizeof(boost::int128::uint128_t)); return std::hash<std::uint64_t>{}(bits.high ^ bits.low); } }; Usually people say that you should not use xor because swapped operands will hash the same. Is there a reason beside performance why xor is used here? I presume because 128 bits (a bit less since some patterns are invalid or encode same value, but definitely more than 64 bits) must collide anyway?