AK: Print leading zeroes after the dot for FixedPoint numbers

As a nearby comment says, "This is a terrible approximation".
This doesn't make things less terrible, but it does make things
more correct in the given framework of terribleness.

Fixes #17156.
This commit is contained in:
Nico Weber 2023-01-23 21:28:10 -05:00 committed by Jelle Raaijmakers
parent 4e06e86438
commit 8b5b767465
Notes: sideshowbarker 2024-07-17 01:20:32 +09:00
2 changed files with 22 additions and 2 deletions

View file

@ -389,6 +389,15 @@ ErrorOr<void> FormatBuilder::put_fixed_point(
auto fraction = (scale * fraction_value) / fraction_one; // TODO: overflows
if (is_negative)
fraction = scale - fraction;
size_t leading_zeroes = 0;
{
auto scale_tmp = scale / 10;
for (; fraction < scale_tmp; ++leading_zeroes) {
scale_tmp /= 10;
}
}
while (fraction != 0 && fraction % 10 == 0)
fraction /= 10;
@ -402,14 +411,20 @@ ErrorOr<void> FormatBuilder::put_fixed_point(
}
}
if (visible_precision == 0)
leading_zeroes = 0;
if (zero_pad || visible_precision > 0)
TRY(string_builder.try_append('.'));
if (leading_zeroes > 0)
TRY(format_builder.put_u64(0, base, false, false, true, Align::Right, leading_zeroes));
if (visible_precision > 0)
TRY(format_builder.put_u64(fraction, base, false, upper_case, true, Align::Right, visible_precision));
if (zero_pad && (precision - visible_precision) > 0)
TRY(format_builder.put_u64(0, base, false, false, true, Align::Right, precision - visible_precision));
if (zero_pad && (precision - leading_zeroes - visible_precision) > 0)
TRY(format_builder.put_u64(0, base, false, false, true, Align::Right, precision - leading_zeroes - visible_precision));
}
TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));

View file

@ -150,4 +150,9 @@ TEST_CASE(formatter)
EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<4>(123.456)), "123.4375"sv);
EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<4>(-123.456)), "-123.4375"sv);
EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16> {}), "0"sv);
EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.1)), "0.09999"sv);
EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.02)), "0.019989"sv);
EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.003)), "0.00299"sv);
EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.0004)), "0.000396"sv);
EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.0000000005)), "0"sv);
}