summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas CHOLLET <lucas.chollet@free.fr>2022-12-18 01:32:20 +0100
committerLinus Groh <mail@linusgroh.de>2023-01-06 16:05:13 +0100
commit85bfeba8c61c9bf6e0dedd99aca0f73f1b253351 (patch)
treecfa8ac8991c919b7b687ea97f462f4d63f60eabb
parent25e39df7ba1554e14756541a12ace692c54c5e0e (diff)
downloadserenity-85bfeba8c61c9bf6e0dedd99aca0f73f1b253351.zip
AK: Support fixed point formatting to print real numbers
-rw-r--r--AK/Format.cpp25
-rw-r--r--AK/Format.h20
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);
}
};