The C11 standard says of %f
and %F
(7.21.6.1:8):
A double argument representing a floating-point number is converted to decimal notation in the style [−]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. If a decimal-point character appears, at least one digit appears before it. The value is rounded to the appropriate number of digits.
Here is a C snippet that produces what you want in a malloc
ed bloc t
, that you need to free up afterwards. If you are writing in C99, a variable-length array can also be considered.
The code below does not introduce any additional approximation to the conversion (if your printf
prints the correctly rounded conversion to decimal, so will the code below), and works for all floating-point values.
#include <stdio.h>
#include <stdlib.h>
…
int len = snprintf(0, 0, "%.2f", input);
if (len < 0) fail();
char *t = malloc((size_t)len + 1);
if (!t) fail();
if (sprintf(t, "%.2f", input) < 0) fail();
len--;
if (t[len] == '0') {
len--;
if (t[len] == '0') {
len--;
if (t[len] == '.') len--;
}
t[len + 1] = '\0';
}
printf( "%.2f\n",
fails at point 3. It prints no exponent when I use it (Clang on Mac OS X) to print either 1E267 or 1E-267. – Lubeck