diff options
author | Lucas CHOLLET <lucas.chollet@free.fr> | 2022-12-18 01:32:20 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-01-06 16:05:13 +0100 |
commit | 85bfeba8c61c9bf6e0dedd99aca0f73f1b253351 (patch) | |
tree | cfa8ac8991c919b7b687ea97f462f4d63f60eabb /AK | |
parent | 25e39df7ba1554e14756541a12ace692c54c5e0e (diff) | |
download | serenity-85bfeba8c61c9bf6e0dedd99aca0f73f1b253351.zip |
AK: Support fixed point formatting to print real numbers
Diffstat (limited to 'AK')
-rw-r--r-- | AK/Format.cpp | 25 | ||||
-rw-r--r-- | AK/Format.h | 20 |
2 files changed, 33 insertions, 12 deletions
diff --git a/AK/Format.cpp b/AK/Format.cpp index 0f52a50dde..9fa6f9e429 100644 --- a/AK/Format.cpp +++ b/AK/Format.cpp @@ -367,7 +367,8 @@ ErrorOr<void> FormatBuilder::put_fixed_point( size_t min_width, size_t precision, char fill, - SignMode sign_mode) + SignMode sign_mode, + RealNumberDisplayMode display_mode) { StringBuilder string_builder; FormatBuilder format_builder { string_builder }; @@ -395,7 +396,7 @@ ErrorOr<void> FormatBuilder::put_fixed_point( { auto fraction_tmp = fraction; for (; visible_precision < precision; ++visible_precision) { - if (fraction_tmp == 0) + if (fraction_tmp == 0 && display_mode != RealNumberDisplayMode::FixedPoint) break; fraction_tmp /= 10; } @@ -425,7 +426,8 @@ ErrorOr<void> FormatBuilder::put_f64( size_t min_width, size_t precision, char fill, - SignMode sign_mode) + SignMode sign_mode, + RealNumberDisplayMode display_mode) { StringBuilder string_builder; FormatBuilder format_builder { string_builder }; @@ -464,7 +466,7 @@ ErrorOr<void> FormatBuilder::put_f64( size_t visible_precision = 0; for (; visible_precision < precision; ++visible_precision) { - if (value - static_cast<i64>(value) < epsilon) + if (value - static_cast<i64>(value) < epsilon && display_mode != RealNumberDisplayMode::FixedPoint) break; value *= 10.0; epsilon *= 10.0; @@ -492,7 +494,8 @@ ErrorOr<void> FormatBuilder::put_f80( size_t min_width, size_t precision, char fill, - SignMode sign_mode) + SignMode sign_mode, + RealNumberDisplayMode display_mode) { StringBuilder string_builder; FormatBuilder format_builder { string_builder }; @@ -531,7 +534,7 @@ ErrorOr<void> FormatBuilder::put_f80( size_t visible_precision = 0; for (; visible_precision < precision; ++visible_precision) { - if (value - static_cast<i64>(value) < epsilon) + if (value - static_cast<i64>(value) < epsilon && display_mode != RealNumberDisplayMode::FixedPoint) break; value *= 10.0l; epsilon *= 10.0l; @@ -794,9 +797,12 @@ ErrorOr<void> Formatter<long double>::format(FormatBuilder& builder, long double { u8 base; bool upper_case; + FormatBuilder::RealNumberDisplayMode real_number_display_mode = FormatBuilder::RealNumberDisplayMode::General; if (m_mode == Mode::Default || m_mode == Mode::FixedPoint) { base = 10; upper_case = false; + if (m_mode == Mode::FixedPoint) + real_number_display_mode = FormatBuilder::RealNumberDisplayMode::FixedPoint; } else if (m_mode == Mode::Hexfloat) { base = 16; upper_case = false; @@ -810,16 +816,19 @@ ErrorOr<void> Formatter<long double>::format(FormatBuilder& builder, long double m_width = m_width.value_or(0); m_precision = m_precision.value_or(6); - return builder.put_f80(value, base, upper_case, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode); + return builder.put_f80(value, base, upper_case, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode, real_number_display_mode); } ErrorOr<void> Formatter<double>::format(FormatBuilder& builder, double value) { u8 base; bool upper_case; + FormatBuilder::RealNumberDisplayMode real_number_display_mode = FormatBuilder::RealNumberDisplayMode::General; if (m_mode == Mode::Default || m_mode == Mode::FixedPoint) { base = 10; upper_case = false; + if (m_mode == Mode::FixedPoint) + real_number_display_mode = FormatBuilder::RealNumberDisplayMode::FixedPoint; } else if (m_mode == Mode::Hexfloat) { base = 16; upper_case = false; @@ -833,7 +842,7 @@ ErrorOr<void> Formatter<double>::format(FormatBuilder& builder, double value) m_width = m_width.value_or(0); m_precision = m_precision.value_or(6); - return builder.put_f64(value, base, upper_case, m_zero_pad, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode); + return builder.put_f64(value, base, upper_case, m_zero_pad, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode, real_number_display_mode); } ErrorOr<void> Formatter<float>::format(FormatBuilder& builder, float value) diff --git a/AK/Format.h b/AK/Format.h index 6dfc1437cd..cb35323e60 100644 --- a/AK/Format.h +++ b/AK/Format.h @@ -150,6 +150,12 @@ public: Default = OnlyIfNeeded, }; + enum class RealNumberDisplayMode { + FixedPoint, + General, + Default = General, + }; + explicit FormatBuilder(StringBuilder& builder) : m_builder(builder) { @@ -200,7 +206,8 @@ public: size_t min_width = 0, size_t precision = 6, char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded); + SignMode sign_mode = SignMode::OnlyIfNeeded, + RealNumberDisplayMode = RealNumberDisplayMode::Default); #ifndef KERNEL ErrorOr<void> put_f80( @@ -211,7 +218,8 @@ public: size_t min_width = 0, size_t precision = 6, char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded); + SignMode sign_mode = SignMode::OnlyIfNeeded, + RealNumberDisplayMode = RealNumberDisplayMode::Default); ErrorOr<void> put_f64( double value, @@ -222,7 +230,8 @@ public: size_t min_width = 0, size_t precision = 6, char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded); + SignMode sign_mode = SignMode::OnlyIfNeeded, + RealNumberDisplayMode = RealNumberDisplayMode::Default); #endif ErrorOr<void> put_hexdump( @@ -520,9 +529,12 @@ struct Formatter<FixedPoint<precision, Underlying>> : StandardFormatter { { u8 base; bool upper_case; + FormatBuilder::RealNumberDisplayMode real_number_display_mode = FormatBuilder::RealNumberDisplayMode::General; if (m_mode == Mode::Default || m_mode == Mode::FixedPoint) { base = 10; upper_case = false; + if (m_mode == Mode::FixedPoint) + real_number_display_mode = FormatBuilder::RealNumberDisplayMode::FixedPoint; } else if (m_mode == Mode::Hexfloat) { base = 16; upper_case = false; @@ -539,7 +551,7 @@ struct Formatter<FixedPoint<precision, Underlying>> : StandardFormatter { i64 integer = value.ltrunk(); constexpr u64 one = static_cast<Underlying>(1) << precision; u64 fraction_raw = value.raw() & (one - 1); - return builder.put_fixed_point(integer, fraction_raw, one, base, upper_case, m_zero_pad, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode); + return builder.put_fixed_point(integer, fraction_raw, one, base, upper_case, m_zero_pad, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode, real_number_display_mode); } }; |