Reputation: 19237
I'd like to format a float so that it has at most 3 fractional digits, but if the last fractional digit(s) are 0 then omit them.
input : expected output
1.1234 : 1.123
1.120 : 1.12
1.100 : 1.1
1.0 : 1
The language doesn't matter as long as it uses the standard formatting C strings, i.e: "%.3f"
The solution I came up with:
function formatShortFloat(value as Float) as String {
var str = value.format("%.3f");
var chars = str.toCharArray();
var end;
for (end = str.length() - 1; chars[end] == '0' && end > 0; --end) {
}
if (chars[end] == '.') {
--end;
}
return str.substring(0, end + 1) as String;
}
or (note, this is Monkey C, there's no easier way to access a char of a string, but that's my problem, that's why I asked for "any language", even pseudo code):
function formatShortFloat(value as Float) as String {
var str = value.format("%.3f");
var end = str.length();
var lastChar;
do {
lastChar = str.substring(end - 1, end);
--end;
} while ("0".equals(lastChar));
if (".".equals(lastChar)) {
--end;
}
return str.substring(0, end + 1) as String;
}
Upvotes: 0
Views: 116
Reputation: 18827
Assuming you always want 3 fractional digits (unless they are zero) and your format-function is compatible with C99 printf
/sprintf
, you can use the %.*g
formatter and provide the number of desired total digits as an extra argument. Assuming your input numbers are not smaller than 0.001
the number you need to pass is (int)(log10(x)+4.0)
. If smaller values occur, I would suggest to manually return "+/-0.001"
or "0"
depending on x
.
Proof-of-concept (in C with some debugging output for comparison -- you can just remove everything starting from \t
and the extra x
):
void println(double x)
{
printf("%.*g\t= %.99g\n", (int)(log10(fabs(x))+4.0), x, x);
}
Godbolt-Demo with some test cases: https://godbolt.org/z/zsxns4h9v
Upvotes: 1