mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-11 00:39:55 +00:00
Fix handling of implicit bit
This commit is contained in:
parent
32d477e5f1
commit
b4a4189d0c
@ -215,11 +215,16 @@ template <typename T> struct bits {
|
|||||||
static_cast<int>(sizeof(T) * std::numeric_limits<unsigned char>::digits);
|
static_cast<int>(sizeof(T) * std::numeric_limits<unsigned char>::digits);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Float> constexpr bool has_implicit_bit() {
|
||||||
|
return std::numeric_limits<Float>::digits != 64;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the number of significand bits in Float excluding the implicit bit.
|
// Returns the number of significand bits in Float excluding the implicit bit.
|
||||||
template <typename Float> constexpr int num_significand_bits() {
|
template <typename Float> constexpr int num_significand_bits() {
|
||||||
// Subtract 1 to account for an implicit most significant bit in the
|
// Subtract 1 to account for an implicit most significant bit in the
|
||||||
// normalized form.
|
// normalized form..
|
||||||
return std::numeric_limits<Float>::digits - 1;
|
return std::numeric_limits<Float>::digits -
|
||||||
|
(has_implicit_bit<Float>() ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A floating-point number f * pow(2, e).
|
// A floating-point number f * pow(2, e).
|
||||||
@ -248,8 +253,9 @@ template <typename F> struct basic_fp {
|
|||||||
// Assume float is in the format [sign][exponent][significand].
|
// Assume float is in the format [sign][exponent][significand].
|
||||||
const int num_float_significand_bits =
|
const int num_float_significand_bits =
|
||||||
detail::num_significand_bits<Float>();
|
detail::num_significand_bits<Float>();
|
||||||
const uint64_t implicit_bit = 1ULL << num_float_significand_bits;
|
|
||||||
using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
|
using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
|
||||||
|
const carrier_uint implicit_bit = carrier_uint(1)
|
||||||
|
<< num_float_significand_bits;
|
||||||
const carrier_uint significand_mask = implicit_bit - 1;
|
const carrier_uint significand_mask = implicit_bit - 1;
|
||||||
auto u = bit_cast<carrier_uint>(n);
|
auto u = bit_cast<carrier_uint>(n);
|
||||||
f = static_cast<uint64_t>(u & significand_mask);
|
f = static_cast<uint64_t>(u & significand_mask);
|
||||||
@ -260,11 +266,11 @@ template <typename F> struct basic_fp {
|
|||||||
// than the smallest normalized number (biased_e > 1).
|
// than the smallest normalized number (biased_e > 1).
|
||||||
bool is_predecessor_closer = f == 0 && biased_e > 1;
|
bool is_predecessor_closer = f == 0 && biased_e > 1;
|
||||||
if (biased_e != 0)
|
if (biased_e != 0)
|
||||||
f += implicit_bit;
|
f += static_cast<uint64_t>(implicit_bit);
|
||||||
else
|
else
|
||||||
biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
|
biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
|
||||||
const int exponent_bias = std::numeric_limits<Float>::max_exponent - 1;
|
const int exponent_bias = std::numeric_limits<Float>::max_exponent - 1;
|
||||||
e = biased_e - exponent_bias - num_float_significand_bits;
|
e = biased_e - exponent_bias - std::numeric_limits<Float>::digits + 1;
|
||||||
return is_predecessor_closer;
|
return is_predecessor_closer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user