Format: Strip trailing zeroes from floating point values
This is a pretty naive implementation that works well. The precision parameter is interpreted as "maximum precision" instead of "minimum precision", which in my opinion is the most useful interpretation.
This commit is contained in:
parent
4bfd394384
commit
c4e19250a1
Notes:
sideshowbarker
2024-07-18 20:39:04 +09:00
Author: https://github.com/gmta Commit: https://github.com/SerenityOS/serenity/commit/c4e19250a17 Pull-request: https://github.com/SerenityOS/serenity/pull/6195
2 changed files with 20 additions and 11 deletions
|
@ -391,7 +391,6 @@ void FormatBuilder::put_f64(
|
|||
FormatBuilder format_builder { string_builder };
|
||||
|
||||
format_builder.put_i64(static_cast<i64>(value), base, false, upper_case, false, Align::Right, 0, ' ', sign_mode);
|
||||
string_builder.append('.');
|
||||
|
||||
if (precision > 0) {
|
||||
// FIXME: This is a terrible approximation but doing it properly would be a lot of work. If someone is up for that, a good
|
||||
|
@ -402,12 +401,22 @@ void FormatBuilder::put_f64(
|
|||
if (value < 0)
|
||||
value = -value;
|
||||
|
||||
for (u32 i = 0; i < precision; ++i)
|
||||
value *= 10;
|
||||
double epsilon = 0.5;
|
||||
for (size_t i = 0; i < precision; ++i)
|
||||
epsilon /= 10.0;
|
||||
|
||||
format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, true, Align::Right, precision);
|
||||
size_t visible_precision = 0;
|
||||
for (; visible_precision < precision; ++visible_precision) {
|
||||
if (value - static_cast<i64>(value) < epsilon)
|
||||
break;
|
||||
value *= 10.0;
|
||||
epsilon *= 10.0;
|
||||
}
|
||||
|
||||
// FIXME: Cut off trailing zeroes by default?
|
||||
if (visible_precision > 0) {
|
||||
string_builder.append('.');
|
||||
format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, true, Align::Right, visible_precision);
|
||||
}
|
||||
}
|
||||
|
||||
put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill);
|
||||
|
|
|
@ -252,11 +252,11 @@ TEST_CASE(file_descriptor)
|
|||
|
||||
TEST_CASE(floating_point_numbers)
|
||||
{
|
||||
EXPECT_EQ(String::formatted("{}", 1.12), "1.120000");
|
||||
EXPECT_EQ(String::formatted("{}", 1.), "1.000000");
|
||||
EXPECT_EQ(String::formatted("{:.3}", 1.12), "1.120");
|
||||
EXPECT_EQ(String::formatted("{}", 1.12), "1.12");
|
||||
EXPECT_EQ(String::formatted("{}", 1.), "1");
|
||||
EXPECT_EQ(String::formatted("{:.3}", 1.12), "1.12");
|
||||
EXPECT_EQ(String::formatted("{:.1}", 1.12), "1.1");
|
||||
EXPECT_EQ(String::formatted("{}", -1.12), "-1.120000");
|
||||
EXPECT_EQ(String::formatted("{}", -1.12), "-1.12");
|
||||
|
||||
// FIXME: There is always the question what we mean with the width field. Do we mean significant digits?
|
||||
// Do we mean the whole width? This is what was the simplest to implement:
|
||||
|
@ -265,12 +265,12 @@ TEST_CASE(floating_point_numbers)
|
|||
|
||||
TEST_CASE(no_precision_no_trailing_number)
|
||||
{
|
||||
EXPECT_EQ(String::formatted("{:.0}", 0.1), "0.");
|
||||
EXPECT_EQ(String::formatted("{:.0}", 0.1), "0");
|
||||
}
|
||||
|
||||
TEST_CASE(yay_this_implementation_sucks)
|
||||
{
|
||||
EXPECT_EQ(String::formatted("{:.0}", .99999999999), "0.");
|
||||
EXPECT_EQ(String::formatted("{:.0}", .99999999999), "0");
|
||||
}
|
||||
|
||||
TEST_CASE(format_nullptr)
|
||||
|
|
Loading…
Add table
Reference in a new issue