diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index ae1f56a6..5c95269e 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -217,8 +217,10 @@ template struct basic_fp { template FMT_CONSTEXPR basic_fp(Float n) { assign(n); } template - using is_supported = bool_constant::is_iec559 && - std::numeric_limits::digits <= 113>; + using is_supported = + bool_constant<(std::numeric_limits::is_iec559 && + std::numeric_limits::digits <= 113) || + is_float128::value>; // Assigns d to this and return true iff predecessor is closer than successor. template ::value)> @@ -229,7 +231,7 @@ template struct basic_fp { << detail::num_significand_bits(); const carrier_uint significand_mask = implicit_bit - 1; auto u = bit_cast(n); - f = static_cast(u & significand_mask); + f = static_cast(u & significand_mask); int biased_e = static_cast((u & exponent_mask()) >> detail::num_significand_bits()); // The predecessor is closer if n is a normalized power of 2 (f == 0) other diff --git a/include/fmt/format.h b/include/fmt/format.h index b1078ca2..de73eae1 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1286,14 +1286,19 @@ template struct decimal_fp { template FMT_API auto to_decimal(T x) noexcept -> decimal_fp; } // namespace dragonbox +// Returns true iff Float has the implicit bit which is not stored. template constexpr bool has_implicit_bit() { + // An 80-bit FP number has a 64-bit significand an no implicit bit. return std::numeric_limits::digits != 64; } -// Returns the number of significand bits in Float excluding the implicit bit. +// Returns the number of significand bits stored in Float. The implicit bit is +// not counted since it is not stored. template constexpr int num_significand_bits() { - return std::numeric_limits::digits - - (has_implicit_bit() ? 1 : 0); + // std::numeric_limits may not support __float128. + return is_float128() ? 112 + : (std::numeric_limits::digits - + (has_implicit_bit() ? 1 : 0)); } template