mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 12:23:15 +00:00
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
|
@ -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…
Reference in a new issue