-10

When I enter the line "printf("%f\n", 5 / 2);" in lines 18 and 21 I don't get 2.5000... but 0.0000 and 65 and I don't understand why.

int main(void){int a = 65;
char c = (char)a;
int m = 3.0/2;
printf("%f\n", 5 / 2);
printf("%c\n", c);              // output: A
printf("%f\n", (float)a);       // output: 65.000000
printf("%f\n", 5 / 2);
printf("%f\n", 5.0 / 2);        // output: 2.5000000
printf("%f\n", 5 / 2.0);        // output: 2.5000000
printf("%f\n", (float)5 / 2);   // output: 2.5000000
printf("%f\n", 5 / (float)2);   // output: 2.5000000
printf("%f\n", (float)(5 / 2)); // output: 2.0000000 - we cast only after division and result was 2
printf("%f\n", 5.0 / 2);        // output: 2.5000000
printf("%d\n", m);              // output: 1
system("PAUSE");
return 0; }

the output is:

0.000000
A
65.000000                                                                   
65.000000
2.500000
2.500000
2.500000
2.500000
2.000000
2.500000
1
APerson
  • 8,140
  • 8
  • 35
  • 49
Yael123
  • 1
  • 1
  • And which one is line 18? – Bathsheba Nov 08 '17 at 13:09
  • 2
    `%f` requests `double`. result of `5 / 2` is `int` (`2`). If you give arguments of a different type from the requesting type, the result is undefined. – BLUEPIXY Nov 08 '17 at 13:11
  • Maybe there's a matching duplicate, but it should be about the core issue (using the wrong printf format specifier). –  Nov 08 '17 at 13:21
  • Possible duplicate of [How to get fractions in an integer division?](https://stackoverflow.com/questions/2976011/how-to-get-fractions-in-an-integer-division) – Mathieu Nov 08 '17 at 13:42
  • @purplepsycho no, that's not a suitable duplicate -- the core issue here is not integer division but using a wrong printf format specifier. –  Nov 08 '17 at 14:35

3 Answers3

3

You can't use %f to format an integer. Doing so invokes undefined behavior. The expression 5 / 2 is equal to the integer 2. You must either use an integer format, such as %d, or else cast it to double to use %f. So change:

printf("%f\n", 5 / 2);

to either:

printf("%d\n", 5 / 2);

or:

printf("%f\n", (double) (5 / 2));
Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
  • ... doing otherwise (as in the original code) is undefined behavior, btw, what will be printed depends on the concrete implementation. –  Nov 08 '17 at 13:14
  • @FelixPalmen Right, you can't predict what it will do if an incompatible format is used. – Tom Karzes Nov 08 '17 at 13:16
  • This was just meant as a possible improvement of your correct (and uv'd) answer, in case OP is interested in "explaining" his output of `0.0` :) –  Nov 08 '17 at 13:18
  • @FelixPalmen Ah ok, I added a comment about it. – Tom Karzes Nov 08 '17 at 13:21
1

From C Standard#7.21.6.1p9

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

The expression 5/2 give the result as integer 2 which is an incorrect type for the conversion specification %f you are using in printf() and is leading to undefined behavior.

In order to get the desired output (i.e. 2.500000), you can typecast the expression with float in printf():

printf("%f\n", (float)5 / 2); // Output: 2.500000

As an alternative, you can multiply 5/2 with 1.0 to get the desired result, like this:

printf("%f\n", 1.0 * 5 / 2); // Output: 2.500000

Caution: Here, make sure that in the expression multiplication with 1.0 should come before 5 / 2, as both multiplication and division have the same precedence and left to right associativity. The result would differ from the desired result for the 5 / 2 * 1.0 expression in printf().

H.S.
  • 11,654
  • 2
  • 15
  • 32
0

The problem is, that the argument in the printf parameter list must match the type specified in the format string. Here

printf("%f\n", (float)a);       // output: 65.000000

you get the output you expect, but here:

printf("%f\n", 5 / 2);

you don't get 2 (the expected result of an integer division), but also 65.00000, since printf() "looks in the wrong place" for the value (i.e. some floating point register, where the result of the integer division isn't located, but the old value from the printf before lingers around).

So, you always have to make sure, that the types of format string and printf parameters match correctly, otherwise undefined behaviour will occur.

Ctx
  • 18,090
  • 24
  • 36
  • 51