mirror of
https://github.com/fmtlib/fmt.git
synced 2026-11-09 14:50:24 +08:00
Fix precision formatting of long double values just below a power of 10 (#5010)
* Fix precision formatting of long double values just below a power of 10 format_dragon included the upper boundary when checking whether the estimated exponent is one too high. This is needed for the shortest output, but with a given precision it left a leading zero digit, so values such as nextafter(1e43L, 0) were printed with an extra digit in fixed notation or a mantissa below 1 in exponent notation. * Apply clang-format
This commit is contained in:
parent
d102a01edf
commit
9c19ea4664
@ -3254,7 +3254,13 @@ FMT_CONSTEXPR20 inline void format_dragon(basic_fp<uint128_t> value,
|
||||
if (!upper) upper = &lower;
|
||||
bool shortest = num_digits < 0;
|
||||
if ((flags & dragon::fixup) != 0) {
|
||||
if (add_compare(numerator, *upper, denominator) + even <= 0) {
|
||||
// In the shortest mode the upper boundary is included because the output
|
||||
// may round up to the next power of 10. With a given number of digits,
|
||||
// rounding happens after digit generation, so only the value is compared.
|
||||
bool too_high =
|
||||
shortest ? add_compare(numerator, *upper, denominator) + even <= 0
|
||||
: compare(numerator, denominator) < 0;
|
||||
if (too_high) {
|
||||
--exp10;
|
||||
numerator *= 10;
|
||||
if (num_digits < 0) {
|
||||
|
||||
@ -1283,6 +1283,16 @@ TEST(format_test, precision) {
|
||||
EXPECT_EQ(
|
||||
fmt::format("{:0g}", std::numeric_limits<long double>::denorm_min()),
|
||||
"3.6452e-4951");
|
||||
|
||||
// Values just below a power of 10 where the initial exponent estimate is
|
||||
// one too high.
|
||||
ld = std::ldexp(static_cast<long double>(0x83126e978d4fdf3bULL), -73);
|
||||
EXPECT_EQ(fmt::format("{:.20e}", ld), "9.99999999999999999958e-04");
|
||||
ld = std::ldexp(static_cast<long double>(0xe596b7b0c643c719ULL), 79);
|
||||
EXPECT_EQ(fmt::format("{:.0f}", ld),
|
||||
"9999999999999999999741184793924429452148736");
|
||||
EXPECT_EQ(fmt::format("{:.19e}", ld), "9.9999999999999999997e+42");
|
||||
EXPECT_EQ(fmt::format("{:.21g}", ld), "9.99999999999999999974e+42");
|
||||
}
|
||||
|
||||
EXPECT_EQ(fmt::format("{:#.0f}", 123.0), "123.");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user