I keep stumbling on the format specifiers for the printf() family of functions. What I want is to be able to print a double (or float) with a maximum given number of digits after the decimal point. If I use:
printf("%1.3f", 359.01335);
printf("%1.3f", 359.00999);
I get
359.013
359.010
Instead of the desired
359.013
359.01
Can anybody help me?
Some of the highly voted solutions suggest the
%g
conversion specifier ofprintf
. This is wrong because there are cases where%g
will produce scientific notation. Other solutions use math to print the desired number of decimal digits.I think the easiest solution is to use
sprintf
with the%f
conversion specifier and to manually remove trailing zeros and possibly a decimal point from the result. Here's a C99 solution:Note that the characters used for digits and the decimal separator depend on the current locale. The code above assumes a C or US English locale.
To get rid of the trailing zeros, you should use the "%g" format:
After the question was clarified a bit, that suppressing zeros is not the only thing that was asked, but limiting the output to three decimal places was required as well. I think that can't be done with sprintf format strings alone. As Pax Diablo pointed out, string manipulation would be required.
A simple solution but it gets the job done, assigns a known length and precision and avoids the chance of going exponential format (which is a risk when you use %g):
Add or remove "elses" if you want a max of 2 decimals; 4 decimals; etc.
For example if you wanted 2 decimals:
If you want to specify the minimum width to keep fields aligned, increment as necessary, for example:
You could also convert that to a function where you pass the desired width of the field:
I like the answer of R. slightly tweaked:
'1000' determines the precision.
Power to the 0.5 rounding.
EDIT
Ok, this answer was edited a few times and I lost track what I was thinking a few years back (and originally it did not fill all the criteria). So here is a new version (that fills all criteria and handles negative numbers correctly):
And the test cases:
And the output of the tests:
Now, all criteria are met:
Unfortunately this answer is a two-liner as
sprintf
does not return the string.Here is my first try at an answer:
Known bugs: Possible buffer overflow depending on format. If "." is present for other reason than %f wrong result might happen.
Your code rounds to three decimal places due to the ".3" before the f
Thus if you the second line rounded to two decimal places, you should change it to this:
That code will output your desired results:
*Note this is assuming you already have it printing on separate lines, if not then the following will prevent it from printing on the same line:
The Following program source code was my test for this answer