Commit 33d3277c authored by Tom Jackson's avatar Tom Jackson Committed by Chip Turner

Support trailing decimals for floats

Summary: So integer-like numbers can be formatted in a manner which disambiguates them from integers.

Test Plan: Unit tests

Reviewed By: tudorb@fb.com

Subscribers: jfh, cscheau

FB internal diff: D1454446
parent ba00a0d4
......@@ -649,6 +649,11 @@ class FormatValue<double> {
break;
};
auto flags =
DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN |
(arg.trailingDot ? DoubleToStringConverter::EMIT_TRAILING_DECIMAL_POINT
: 0);
double val = val_;
switch (arg.presentation) {
case '%':
......@@ -660,13 +665,14 @@ class FormatValue<double> {
DoubleToStringConverter::kMaxFixedDigitsAfterPoint) {
arg.precision = DoubleToStringConverter::kMaxFixedDigitsAfterPoint;
}
DoubleToStringConverter conv(
DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN,
infinitySymbol,
nanSymbol,
exponentSymbol,
-4, arg.precision,
0, 0);
DoubleToStringConverter conv(flags,
infinitySymbol,
nanSymbol,
exponentSymbol,
-4,
arg.precision,
0,
0);
arg.enforce(conv.ToFixed(val, arg.precision, &builder),
"fixed double conversion failed");
}
......@@ -678,13 +684,14 @@ class FormatValue<double> {
arg.precision = DoubleToStringConverter::kMaxExponentialDigits;
}
DoubleToStringConverter conv(
DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN,
infinitySymbol,
nanSymbol,
exponentSymbol,
-4, arg.precision,
0, 0);
DoubleToStringConverter conv(flags,
infinitySymbol,
nanSymbol,
exponentSymbol,
-4,
arg.precision,
0,
0);
arg.enforce(conv.ToExponential(val, arg.precision, &builder));
}
break;
......@@ -698,13 +705,14 @@ class FormatValue<double> {
DoubleToStringConverter::kMaxPrecisionDigits) {
arg.precision = DoubleToStringConverter::kMaxPrecisionDigits;
}
DoubleToStringConverter conv(
DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN,
infinitySymbol,
nanSymbol,
exponentSymbol,
-4, arg.precision,
0, 0);
DoubleToStringConverter conv(flags,
infinitySymbol,
nanSymbol,
exponentSymbol,
-4,
arg.precision,
0,
0);
arg.enforce(conv.ToShortest(val, &builder));
}
break;
......
......@@ -96,7 +96,15 @@ void FormatArg::initSlow() {
while (p != end && *p >= '0' && *p <= '9') {
++p;
}
precision = to<int>(StringPiece(b, p));
if (p != b) {
precision = to<int>(StringPiece(b, p));
if (p != end && *p == '.') {
trailingDot = true;
++p;
}
} else {
trailingDot = true;
}
if (p == end) return;
}
......
......@@ -46,6 +46,7 @@ struct FormatArg {
sign(Sign::DEFAULT),
basePrefix(false),
thousandsSeparator(false),
trailingDot(false),
width(kDefaultWidth),
precision(kDefaultPrecision),
presentation(kDefaultPresentation),
......@@ -128,6 +129,11 @@ struct FormatArg {
*/
bool thousandsSeparator;
/**
* Force a trailing decimal on doubles which could be rendered as ints
*/
bool trailingDot;
/**
* Field width
*/
......
......@@ -124,7 +124,7 @@ Format string (`vformat`):
- `format_spec`: format specification, see below
Format specification:
`[[fill] align] [sign] ["#"] ["0"] [width] [","] ["." precision] [type]`
`[[fill] align] [sign] ["#"] ["0"] [width] [","] ["." precision] ["."] [type]`
- `fill` (may only be specified if `align` is also specified): pad with this
character ('` `' (space) or '`0`' (zero) might be useful; space is default)
......@@ -149,6 +149,8 @@ Format specification:
- for floating point values, number of digits after decimal point ('`f`' or
'`F`' presentation) or number of significant digits ('`g`' or '`G`')
- for others, maximum field size (truncate subsequent characters)
- '`.`' (when used after precision or in lieu of precison): Forces a trailing
decimal point to make it clear this is a floating point value.
- `type`: presentation format, see below
Presentation formats:
......
......@@ -239,6 +239,13 @@ TEST(Format, Float) {
EXPECT_EQ("0.10", sformat("{:.2f}", 0.1));
EXPECT_EQ("0.01", sformat("{:.2f}", 0.01));
EXPECT_EQ("0.00", sformat("{:.2f}", 0.001));
EXPECT_EQ("100000.", sformat("{:.}", 100000.0));
EXPECT_EQ("1e+6", sformat("{:.}", 1000000.0));
EXPECT_EQ(" 100000.", sformat("{:8.}", 100000.0));
EXPECT_EQ("100000.", sformat("{:4.}", 100000.0));
EXPECT_EQ(" 100000", sformat("{:8.8}", 100000.0));
EXPECT_EQ(" 100000.", sformat("{:8.8.}", 100000.0));
}
TEST(Format, MultiLevel) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment