I'd like to print floats via printf as follows:
8)0s after .1.0 as "1."With g I cannot achieve (3), with f I cannot achieve (2,3).
From the docs it seems that # would do the trick for (3)
Used with a, A, e, E, f, F, g or G it forces the written output to contain a decimal point even if no more digits follow. By default, if no digits follow, no decimal point is written.
So #g can achieve (3), but it unfortunately does more than is written there: it also breaks the feature (2) by removing also relevant decimal digits (see below).
Here are some examples I tried, the last line shows what I am looking for:
| number | 1.0 | -1.0 | 1.9 | -999.1 | 1.000001 |
|---|---|---|---|---|---|
%8.2g |
1 |
-1 |
1.9 |
-1e+03 |
1 |
%8.g |
1 |
-1 |
2 |
-1e+03 |
1 |
%8g |
1 |
-1 |
1.9 |
-999.1 |
1 |
%#8.2g |
1.0 |
-1.0 |
1.9 |
-1.0e+03 |
1.0 |
%#8.g |
1. |
-1. |
2. |
-1.e+03 |
1. |
%#8g |
1.00000 |
-1.00000 |
1.90000 |
-999.100 |
1.00000 |
%8.2f |
1.00 |
-1.00 |
1.90 |
-999.10 |
1.00 |
%8.f |
1 |
-1 |
2 |
-999 |
1 |
%8f |
1.000000 |
-1.000000 |
1.900000 |
-999.099976 |
1.000001 |
%#8.2f |
1.00 |
-1.00 |
1.90 |
-999.10 |
1.00 |
%#8.f |
1. |
-1. |
2. |
-999. |
1. |
%#8f |
1.000000 |
-1.000000 |
1.900000 |
-999.099976 |
1.000001 |
???? |
1. |
-1. |
1.9 |
-999.1 |
1.000001 |
Can somebody help how to achieve the wanted output in the last line?
Suggestions:
Modify goal
Use "%8g" as that is standard and closest to OP's goal.
Post process output
"#" in "%g" modifies 2 things: a '.' is always printed and trailing zeroes are not discarded. OP seems to want just the first feature.
Use "%#*.*g", n, n-1, ... and post-process the string.
This is tricky and deserves extensive testing.
Do not
Pre-process the float before printing. Edge cases will catch you.
Add text in post processing. Edge cases will catch you.
"%e" does not provide non-exponential form.
"%f" can make for long output with values like -FLT_MAX.
Sample code. Simplifications exists.
#include <stdio.h>
int main() {
float val[] = {1.0, -1.0, 1.9f, -999.1f, 1.000001f};
size_t v_n = sizeof val / sizeof val[0];
puts("???? 1. -1. 1.9 -999.1 1.000001");
fputs(" ", stdout);
for (size_t v_i = 0; v_i < v_n; v_i++) {
double v = val[v_i];
char s[100];
int n = 8;
snprintf(s, sizeof s, "%#*.*g", n, n - 1, v);
char *dot = strchr(s, '.');
if (dot) {
char *begin = dot + 1;
begin = begin + strspn(begin, "0123456789");
char *end = begin;
while (begin[-1] == '0')
begin--;
if (begin < end) {
//printf("xx: <%s> <%s>\n", begin, end);
size_t len = strlen(end);
memmove(begin, end, len + 1);
}
}
printf(" %-13s", s);
}
}
Output
???? 1. -1. 1.9 -999.1 1.000001
1. -1. 1.9 -999.1 1.000001
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With