Float Formatting in C++

C: printf a float value

You can do it like this:

printf("%.6f", myFloat);

6 represents the number of digits after the decimal separator.

C printf format for float

The first number in the format string is the minimum field width, which includes all of the characters, including the decimal point. In your case, the field width needs to be at least 4 for the decimal points to line up.

So you want

int main( void )
{
float a = 1.0, b = 25.16;
printf("%4.1f\n", a);
printf("%4.1f\n", b);
}

Formatting floating point numbers in C

That's not a problem with scanning. That is a problem with printf formatting.

From the documentation (emphasis mine):

f, F

The double argument shall be converted to decimal notation in the style "[-]ddd.ddd", where the number of digits after the radix character is equal to the precision specification. If the precision is missing, it shall be taken as 6; if the precision is explicitly zero and no '#' flag is present, no radix character shall appear. If a radix character appears, at least one digit appears before it. The low-order digit shall be rounded in an implementation-defined manner.

You probably want %g (again, emphasis mine):

g, G

The double argument shall be converted in the style f or e (or in the style F or E in the case of a G conversion specifier), with the precision specifying the number of significant digits. If an explicit precision is zero, it shall be taken as 1. The style used depends on the value converted; style e (or E ) shall be used only if the exponent resulting from such a conversion is less than -4 or greater than or equal to the precision. Trailing zeros shall be removed from the fractional portion of the result; a radix character shall appear only if it is followed by a digit or a '#' flag is present.

Printf width specifier to maintain precision of floating-point value

I recommend @Jens Gustedt hexadecimal solution: use %a.

OP wants “print with maximum precision (or at least to the most significant decimal)”.

A simple example would be to print one seventh as in:

#include <float.h>
int Digs = DECIMAL_DIG;
double OneSeventh = 1.0/7.0;
printf("%.*e\n", Digs, OneSeventh);
// 1.428571428571428492127e-01

But let's dig deeper ...

Mathematically, the answer is "0.142857 142857 142857 ...", but we are using finite precision floating point numbers.
Let's assume IEEE 754 double-precision binary.
So the OneSeventh = 1.0/7.0 results in the value below. Also shown are the preceding and following representable double floating point numbers.

OneSeventh before = 0.1428571428571428 214571170656199683435261249542236328125
OneSeventh = 0.1428571428571428 49212692681248881854116916656494140625
OneSeventh after = 0.1428571428571428 769682682968777953647077083587646484375

Printing the exact decimal representation of a double has limited uses.

C has 2 families of macros in <float.h> to help us.

The first set is the number of significant digits to print in a string in decimal so when scanning the string back,
we get the original floating point. There are shown with the C spec's minimum value and a sample C11 compiler.

FLT_DECIMAL_DIG   6,  9 (float)                           (C11)
DBL_DECIMAL_DIG 10, 17 (double) (C11)
LDBL_DECIMAL_DIG 10, 21 (long double) (C11)
DECIMAL_DIG 10, 21 (widest supported floating type) (C99)

The second set is the number of significant digits a string may be scanned into a floating point and then the FP printed, still retaining the same string presentation. There are shown with the C spec's minimum value and a sample C11 compiler. I believe available pre-C99.

FLT_DIG   6, 6 (float)
DBL_DIG 10, 15 (double)
LDBL_DIG 10, 18 (long double)

The first set of macros seems to meet OP's goal of significant digits. But that macro is not always available.

#ifdef DBL_DECIMAL_DIG
#define OP_DBL_Digs (DBL_DECIMAL_DIG)
#else
#ifdef DECIMAL_DIG
#define OP_DBL_Digs (DECIMAL_DIG)
#else
#define OP_DBL_Digs (DBL_DIG + 3)
#endif
#endif

The "+ 3" was the crux of my previous answer.
Its centered on if knowing the round-trip conversion string-FP-string (set #2 macros available C89), how would one determine the digits for FP-string-FP (set #1 macros available post C89)? In general, add 3 was the result.

Now how many significant digits to print is known and driven via <float.h>.

To print N significant decimal digits one may use various formats.

With "%e", the precision field is the number of digits after the lead digit and decimal point.
So - 1 is in order. Note: This -1 is not in the initial int Digs = DECIMAL_DIG;

printf("%.*e\n", OP_DBL_Digs - 1, OneSeventh);
// 1.4285714285714285e-01

With "%f", the precision field is the number of digits after the decimal point.
For a number like OneSeventh/1000000.0, one would need OP_DBL_Digs + 6 to see all the significant digits.

printf("%.*f\n", OP_DBL_Digs    , OneSeventh);
// 0.14285714285714285
printf("%.*f\n", OP_DBL_Digs + 6, OneSeventh/1000000.0);
// 0.00000014285714285714285

Note: Many are use to "%f". That displays 6 digits after the decimal point; 6 is the display default, not the precision of the number.

Formatting float value in C language

Continuing from my comment to Florian's answer, the format of "%0g" will print the shortest representation with the leading-zero, e.g.

#include <stdio.h>

int main (void) {

float f[] = { .5, .56, .567 };
size_t n = sizeof f/sizeof *f;

for (size_t i = 0; i < n; i++)
printf ("%0g\n", f[i]);

return 0;
}

Example Use/Output

$ ./bin/floatfmt
0.5
0.56
0.567

Float formatting in C++

You need to include <iomanip> and provide namespace scope to setw and setprecision

#include <iomanip>
std::setw(2)
std::setprecision(5)

try:

cout.precision(5);
cout << "Total : " << setw(4) << floor(total*100)/100 << endl;

or

 cout << "Total : " << setw(4)   << ceil(total*10)/10 << endl;

iostream provides precision function, but to use setw, you may need to include extra header file.

How to format a float number to the right in C?

What you've posted will fit the whole float into a 6 char wide column with the .xx taking up the last 3. If you want the integer portion in a six char wide column with the '.' and the fractional portion after these 6 characters, its %9.2f. Quick example program to show the differences

#include <stdio.h>

int main(void) {
float x = 83.4;
printf("....|....|....|\n");
printf("%6.2f\n", x); // prints " 83.40"
printf("%9.2f\n", x); // prints " 83.40"

return 0;
}

And the output:

....|....|....|
83.40
83.40

Correct format specifier for double in printf

"%f" is the (or at least one) correct format for a double. There is no format for a float, because if you attempt to pass a float to printf, it'll be promoted to double before printf receives it1. "%lf" is also acceptable under the current standard -- the l is specified as having no effect if followed by the f conversion specifier (among others).

Note that this is one place that printf format strings differ substantially from scanf (and fscanf, etc.) format strings. For output, you're passing a value, which will be promoted from float to double when passed as a variadic parameter. For input you're passing a pointer, which is not promoted, so you have to tell scanf whether you want to read a float or a double, so for scanf, %f means you want to read a float and %lf means you want to read a double (and, for what it's worth, for a long double, you use %Lf for either printf or scanf).



1. C99, §6.5.2.2/6: "If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions." In C++ the wording is somewhat different (e.g., it doesn't use the word "prototype") but the effect is the same: all the variadic parameters undergo default promotions before they're received by the function.

Is there a way to automatically printf a float to the number of decimal places it has?

Is there a way to automatically printf a float to the number of decimal places it has?

Use "%g". "%g" lops off trailing zero digits.

... unless the # flag is used, any trailing zeros are removed from the fractional portion of the result and the decimal-point character is removed if there is no fractional portion remaining. C17dr § 7.21.6.1 8.

All finite floating point values are exactly representable in decimal - some need many digits to print exactly. Up to DBL_DECIMAL_DIG from <float.h> (typically 17) significant digits is sufficient - rarely a need for more.

Pass in a precision to encourage enough output, but not too much.

Remember values like 0.00008 are not exactly encoded in the typical binary floating point double, but a nearby value is used like 8.00000000000000065442...e-05

printf("%.*g\n", DBL_DECIMAL_DIG, some_double);

printf("%.17g, %.17g, %.17g, %.17g\n", 1.27, 345.1415926535, 1.22013, 0.00008);
// 1.27, 345.14159265350003, 1.2201299999999999, 8.0000000000000007e-05

DBL_DIG (e.g. 15) may better meet OP's goal.

printf("%.15g, %.15g, %.15g, %.15g\n", 1.27, 345.1415926535, 1.22013, 0.00008);
// 1.27, 345.1415926535, 1.22013, 8e-05

Function to print a double - exactly may take 100s of digits.



Related Topics



Leave a reply



Submit