简体   繁体   中英

why result of (double + int) is 0 (C language)

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?

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.

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

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.

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).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM