c-programming output printf()
Hi guys,
I have a question to following code: `
#include <stdio.h>
int main() {
printf("%f\n", (8/5)/2);
printf("%f\n", (float) 5/2);
printf("%f\n", (8/5)/2);
return 0;
}
Line 3 and five are the same. But output isn´t it. Why is that? I have no declaration of variables just printf()
Output:
0.000000
2.500000
2.500000
But if I invert line 4 and 5 then output is same to line 3 as it should be.
#include <stdio.h>
int main() {
printf("%f\n", (8/5)/2);
printf("%f\n", (8/5)/2);
printf("%f\n", (float) 5/2);
return 0;
}
0.000000
0.000000
2.500000
Can anybody explain the output of this code?
CodePudding user response:
As I noted in a comment:
On machines such as x86/64 architecture, floating point values are passed in one set of registers; integers in a different set of registers. Once the floating point register is set to 2.5, the integer arithmetic doesn't change it. The behaviour is undefined, but that's an explanation of what happens. Try:
printf("%f %d\n", 355.0/113.0, 355/113); printf("%f %d\n", 355/113, 355.0/113.0);
Given what you're seeing, I expect you to see the same output twice. My Mac gives the same answer twice, even though the arguments are reordered.
Source:
#include <stdio.h>
int main(void)
{
printf("%f %d\n", 355.0/113.0, 355/113);
printf("%f %d\n", 355/113, 355.0/113.0);
return 0;
}
Output:
3.141593 3
3.141593 3
I note that I have to avoid my default compilation options — otherwise, it doesn't compile.
Default compilation:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -fno-common -c fl43.c
fl43.c: In function ‘main’:
fl43.c:6:14: error: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Werror=format=]
6 | printf("%f %d\n", 355/113, 355.0/113.0);
| ~^ ~~~~~~~
| | |
| double int
| %d
fl43.c:6:17: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘double’ [-Werror=format=]
6 | printf("%f %d\n", 355/113, 355.0/113.0);
| ~^ ~~~~~~~~~~~
| | |
| int double
| %f
cc1: all warnings being treated as errors
$
CodePudding user response:
While your code will compile, you should receive warnings about passing an int
where a double
was expected. The result is undefined behavior.
% gcc test.c
test.c:3:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
printf("%f\n", (8/5)/2);
~~ ^~~~~~~
%d
test.c:5:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
printf("%f\n", (8/5)/2);
~~ ^~~~~~~
%d
2 warnings generated.
CodePudding user response:
It is one big undefined behaviour as you pass integer but ask printf
to print double
You need to to cast the result:
printf("%f\n", (double)((8/5)/2));
printf("%f\n", (double) 5/2);
printf("%f\n", (double)((8/5)/2));