12

C++: What is the printf() format spec for float? (Visual C++)

It used to be that I used %g for float and %lg for double.

It looks like the spec changed and float is undefined and double is %g.

I have bits in memory that I am printing out so casting is not an option.

Is there a way that I can print out float values using printf() ?

Update:

This code was written for unit testing generic C++ libs used on an embedded system. Here's what I had to do to get the float to work. The code is in a template function:

template <typename T,typename TTYP,typename Ttyp,int bits,bool IsSigned> 
Error testMatrixT() 
{ ...

Here is a code snip:

if (typeid(Ttyp) == typeid(float)) {    
    float64 c = *(float32*)&Tp(row,col);
    float64 a1 = *(float32*)&Arg1(row,col);
    float64 a2 = *(float32*)&Arg2(row,col);
    float64 e = *(float32*)&Exp(row,col);
    m_b = (c == e);
    _snprintf(m_acDiag, sizeof(m_acDiag)-1
        , "add(Arg1,Arg2): arg1=%g, arg2=%g, Expected=%g, Actual=%g, Result: %s"
        , a1, a2, e, c, BOOL_PF(m_b));
} else {
    ...

Pretty ugly isn't it? Using floats as args give bad output. Maybe due to using _snprintf() ? Years ago I would use %lg and it would be OK. Not anymore.

Ajay
  • 18,086
  • 12
  • 59
  • 105
Michael Fitzpatrick
  • 682
  • 3
  • 8
  • 18

6 Answers6

25

double and float use the same format specifiers with printf (%a, %e, %f, and %g). This is because printf is a variadic function. Any float arguments are implicitly promoted to double before the call; you can't actually pass a float to printf.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
4

To the question in title: There is none / "%f"

To the question in message body: Yes and no.

printf is a variadic function. All float arguments are automatically promoted to doubles. You print a float by passing it to printf, but no float actually reaches the printf function.

eq-
  • 9,986
  • 36
  • 38
3

Others have pointed out the format for printing float using printf, but, since you're using C++, my suggestion is to avoid this completely.

Use C++ streams instead, you don't have to worry about format specifiers then. It is also type safe, while printf isn't.

#include <iostream>

int main()
{
  float f = 1.234;
  std::cout << f << std::endl;
}

If you have an array of bytes containing a float, memcpy it into a float variable and use the above code.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • I ended up using streams, but I think this is a temporary solution since I am sure we will eventually run this on an embedded platform without STL support. It looks to me that floats are deprecated since there is no format spec for it and it doesn't work as an arg to printf unless I cast it to a double. – Michael Fitzpatrick Aug 26 '11 at 17:19
3

%g has always been the correct format for either float or double (since float arguments are promoted to double for variadic functions like printf).

%lg was added as a synonym for %g (in C99, I don't know when or whether C++ adopted it), probably for better symmetry with the *scanf family.

$Lg is for long double.

You can replace g with f or e in the above, depending on what output format you want.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

From: http://www.cplusplus.com/reference/clibrary/cstdio/printf/

%f Decimal floating point 392.65

Kiley Naro
  • 1,749
  • 1
  • 14
  • 20
1
printf("float: %f", floatValue);

or if you want exponential notation:

printf("float: %e", floatValue);
SSteve
  • 10,550
  • 5
  • 46
  • 72