Reputation: 113
result of
printf("%d\n", 5.0 + 2);
is 0
but
int num = 5.0 + 2;
printf("%d\n", num);
is 7
What's the difference between the two?
Upvotes: 5
Views: 1238
Reputation: 60058
5.0+2
is typed double
.
The compiler warning for
int main() { return _Generic(5.0 + 2, struct foo: 0); }
should tell you as much if
int main() { return _Generic(5.0 + 2, double: 5.0+2); }
compiling without error doesn't.
Matching "%d"
with a double
in printf
results in undefined behavior.
Any result is legal, including your harddrive getting erased (unlikely to happen unless your program already has such functionality somewhere in it; if it does, UB can well result it it being inadvertently invoked).
Upvotes: 1
Reputation: 158
The usual arithmetic conversions are implicitly performed to cast their values to a common type. The compiler first performs integer promotion; if the operands still have different types, then they are converted to the type that appears highest in the following hierarchy -
In int num = 5.0 + 2;
this code snippet you are adding a float with integer and storing back to integer again. So, c automatically casts the result into integer to store in an integer type variable. So, while printing using %d, it prints fine.
But, in printf("%d\n", 5.0 + 2);
this code snippet, the addition is casted into floating point number as float has higher priority over integer, but you are printing it using %d. Here mismatch of format specifier causing the unexpected result.
Upvotes: 0
Reputation: 409166
The result of 5.0 + 2
is 7.0
and is of type double
.
The "%d"
format is to print int
.
Mismatching format specification and argument type leads to undefined behavior.
To print a float
or double
value with printf
you should use the format "%f"
.
With
int num = 5.0 + 2;
you convert the result of 5.0 + 2
into the int
value 7
. Then you print the int
value using the correct format specifier.
Upvotes: 9
Reputation: 35154
The result of expression 5.0 + 2
is of type double
, since at least one of the two operands of operator +
here is a floating point / double value (so the other one will be converted to double
before adding).
If you write printf("%d\n", 5.0 + 2)
, you will pass a floating point value where the format specifier actually expects an int
. This mismatch is undefined behaviour, and the 0
you receive could be something else (another number, a crash, a .... what ever), too.
int num = 5.0 + 2
, in contrast, will convert the double
-value resulting from 5.0 + 2
back to an integral value (discarding any fractional part). So the value of num
will be 7
and will be - since num
is an integral type - valid in conjunction with format specifier %d
then.
Upvotes: 3
Reputation: 213720
In all expressions, every operand has a type. 5.0
has type double
. 2
has type int
.
Whenever a double and an integer are used as operands of the same operator, the integer is silently converted to a double before calculation. The result is of type double
.
And so you pass double
to printf
, but you have told it to expect an int
, since you used %d
. The result is a bug, the outcome is not defined.
But in case of int num = 5.0 + 2;
, you first get a result as double
, 7.0
. Then force a conversion back to int
. That code is equivalent to:
int num = (int)((double)5.0 + (double)2);
More details here: Implicit type promotion rules
Upvotes: 6