Roshan Kumar
Roshan Kumar

Reputation: 11

Puzzled about printf output

While using printf with %d as format specifier and giving a float as an argument e.g, 2.345, it prints 1546188227. So, I understand that it may be due to the conversion of single point float precision format to simple decimal format. But when we print 2.000 with the %d as format specifier, then why it prints 0 only ? Please help.

Upvotes: 1

Views: 297

Answers (6)

Sergei Nikulov
Sergei Nikulov

Reputation: 5110

Here what ISO/IEC 9899:1999 standard $7.19.6 states:

If a conversion specification is invalid, the behavior is undefined.239)
If any argument is not the correct type for the corresponding conversion
specification, the behavior is undefined.

Upvotes: 1

Employed Russian
Employed Russian

Reputation: 213436

Go here, enter 2.345, click "rounded". Observe 64-bit hex value: 4002C28F5C28F5C3. Observe that 1546188227 is 0x5c28f5c3.

Now repeat for 2.00. Observe that 64-bit hex value is 4000000000000000

P.S. When you say that you give a float argument, what you apparently mean is that you give a double argument.

Upvotes: 1

AnT stands with Russia
AnT stands with Russia

Reputation: 320391

Format specifier %d can only be used with values of type int (and compatible types). Trying to use %d with float or any other types produces undefined behavior. That's the only explanation that truly applies here. From the language point of view the output you see is essentially random. And you are not guaranteed to get any output at all.

If you are still interested in investigating the specific reason for the output you see (however little sense it makes), you'll have to perform a platform-specific investigation, because the actual behavior depends critically on various implementation details. And you are not even mentioning your platform in your post.

In any case, as a side note, note that it is impossible to pass float values as variadic arguments to variadic functions. float values in such cases are always converted to double and passed as double. So in your case it is double values you are attempting to print. Behavior is still undefined though.

Upvotes: 4

Thomas Padron-McCarthy
Thomas Padron-McCarthy

Reputation: 27632

First a small nitpick: The literal 2.345 is actually of the type double, not float, and besides, even a float, such as the literal 2.345f, would be converted to double when used as an argument to a function that takes a variable number of arguments, such as printf.

But what happens here is that the (typically) 64 bits of the double value is sent to printf, and then it interprets (typically) 32 of those bits as an integer value. So it just happens that those bits were zero.

According to the standard, this is what is called undefined behavior: The compiler is allowed to do anything at all.

Upvotes: 0

LeleDumbo
LeleDumbo

Reputation: 9340

When you use printf with wrong format specifier for the corresponding argument, the result is undefined behavior. It could be anything and may differ from one implementation to another. Only correct use of format specified has defined behavior.

Upvotes: 0

Wug
Wug

Reputation: 13196

If you're trying to make it print integer values, cast the floats to ints in the call:

printf("ints: %d %d", (int) 2.345, (int) 2.000);

Otherwise, use the floating point format identifier:

printf("floats: %f %f", 2.345, 2.000);

Upvotes: 0

Related Questions