AK: Add binary and octal mode formatting for FixedPoint

This commit is contained in:
ronak69 2023-08-14 08:58:33 +00:00 committed by Andrew Kaster
parent 352480338e
commit 2caf68fd03
Notes: sideshowbarker 2024-07-17 03:35:16 +09:00
3 changed files with 23 additions and 6 deletions

View file

@ -419,16 +419,21 @@ struct Formatter<FixedPoint<precision, Underlying>> : StandardFormatter {
ErrorOr<void> format(FormatBuilder& builder, FixedPoint<precision, Underlying> value)
{
u8 base;
bool upper_case;
bool upper_case = false;
if (m_mode == Mode::Default || m_mode == Mode::FixedPoint) {
base = 10;
upper_case = false;
} else if (m_mode == Mode::Hexfloat) {
base = 16;
upper_case = false;
} else if (m_mode == Mode::HexfloatUppercase) {
base = 16;
upper_case = true;
} else if (m_mode == Mode::Binary) {
base = 2;
} else if (m_mode == Mode::BinaryUppercase) {
base = 2;
upper_case = true;
} else if (m_mode == Mode::Octal) {
base = 8;
} else {
VERIFY_NOT_REACHED();
}

View file

@ -403,9 +403,10 @@ ErrorOr<void> FormatBuilder::put_fixed_point(
// FIXME: overflows (not before: fraction_value = (2^precision - 1) and precision >= 20) (use wider integer type)
auto fraction = scale * fraction_value;
TRY(format_builder.put_u64(fraction, base, false, upper_case, true, use_separator, Align::Right, precision));
} else if (base == 16) {
auto fraction = fraction_value << ((4 - (precision % 4)) % 4);
TRY(format_builder.put_u64(fraction, base, false, upper_case, false, use_separator, Align::Right, precision/4 + (precision % 4 != 0), '0'));
} else if (base == 16 || base == 8 || base == 2) {
auto bits_per_character = log2(base);
auto fraction = fraction_value << ((bits_per_character - (precision % bits_per_character)) % bits_per_character);
TRY(format_builder.put_u64(fraction, base, false, upper_case, false, use_separator, Align::Right, precision / bits_per_character + (precision % bits_per_character != 0), '0'));
} else {
VERIFY_NOT_REACHED();
}

View file

@ -234,7 +234,18 @@ TEST_CASE(formatter)
// EXPECT_EQ(DeprecatedString::formatted("{:0.30}", AK::FixedPoint<28, u64>::create_raw(1)), "0.000000003725290298461914062500"sv);
EXPECT_EQ(DeprecatedString::formatted("{:a}", FixedPoint<16>(42.42)), "2a.6b85"sv);
EXPECT_EQ(DeprecatedString::formatted("{:o}", FixedPoint<16>(42.42)), "52.327024"sv);
EXPECT_EQ(DeprecatedString::formatted("{:b}", FixedPoint<16>(42.42)), "101010.01101"sv);
EXPECT_EQ(DeprecatedString::formatted("{:0.10a}", FixedPoint<16>(69.69)), "45.b0a4000000"sv);
EXPECT_EQ(DeprecatedString::formatted("{:0.10o}", FixedPoint<16>(69.69)), "105.5412200000"sv);
EXPECT_EQ(DeprecatedString::formatted("{:0.10b}", FixedPoint<16>(69.69)), "1000101.1011000010"sv);
EXPECT_EQ(DeprecatedString::formatted("{:.30o}", AK::FixedPoint<13, u64>::create_raw(1)), "0.00004"sv);
EXPECT_EQ(DeprecatedString::formatted("{:.30b}", AK::FixedPoint<13, u64>::create_raw(1)), "0.0000000000001"sv);
EXPECT_EQ(DeprecatedString::formatted("{:.30o}", AK::FixedPoint<21, u64>::create_raw(0211234567)), "21.1234567"sv);
EXPECT_EQ(DeprecatedString::formatted("{:.30b}", AK::FixedPoint<13, u64>::create_raw(0b110011011010110)), "11.001101101011"sv);
EXPECT_EQ(DeprecatedString::formatted("{:.30o}", AK::FixedPoint<11, u64>::create_raw((1ull << 11) - 1)), "0.7776"sv);
EXPECT_EQ(DeprecatedString::formatted("{:.30b}", AK::FixedPoint<11, u64>::create_raw((1ull << 11) - 1)), "0.11111111111"sv);
// maximum fraction per precision rendered in hexadecimal; 1 - 2^-precision; no overflow
EXPECT_EQ(DeprecatedString::formatted("{:.30a}", AK::FixedPoint<7, u64>::create_raw((1ull << 7) - 1)), "0.fe"sv);