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?
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
$
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.
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));
Related
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?
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
$
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.
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));
I'm trying to write a code in c to approximate the value of pi using a while loop. I know it is much easier to do so with a for loop but I'm trying to do so using while.
the formula I'm using to do so is in link below:
https://www.paulbui.net/wl/Taylor_Series_Pi_and_e
and the code I wrote looks like this:
#include <stdio.h>
#include <math.h>
int main(){
long n=10;
while(n>0){
double a=0;
a+=((pow(-1,n))/((2*n)+1));
n=n-1;
printf("%ld",4*a);
}
return 0;
}
the reason I used long and double type is that I wanted to do the approximation to a good preciseness but first I should do st for this problem.
thanks in advance.
You have to move a initialization before loop and make stop condition - for example, evaluating current summand. Also it is worth to calculate sign incrementally without using pow:
double a=0;
double eps= 1.0e-6; //note this series has rather slow convergence
n = 0;
double tx = 1.0;
double t = 1.0;
while(abs(tx)>eps){
tx = t / (2*n+1));
a+= tx;
printf("%f",4*a);
n++;
t = - t;
}
The posted code does not cleanly compile!
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled.c" -o "untitled.o"
untitled.c: In function ‘main’:
untitled.c:7:19: warning: conversion from ‘long int’ to ‘double’ may change value [-Wconversion]
7 | a+=((pow(-1,n))/((2*n)+1));
| ^
untitled.c:7:22: warning: conversion from ‘long int’ to ‘double’ may change value [-Wconversion]
7 | a+=((pow(-1,n))/((2*n)+1));
| ^
untitled.c:9:17: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘double’ [-Wformat=]
9 | printf("%ld",4*a);
| ~~^ ~~~
| | |
| | double
| long int
| %f
Compilation finished successfully.
Note: when there are warnings, fix those warnings. Also, when there are warnings, the compiler outputs it's best guess which is not necessarily what you wanted.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
My program is to get (a^b)%c .
my program -
#include <stdio.h>
#include <math.h>
double powfunction (double x, double y)
{
double answer = pow(x,y);
return answer;
}
int main()
{
int t, result, c, asign;
double a, b;
scanf("%d",&t);
for(t;t>0;t--){
scanf("%lf %lf %d",&a,&b,&c);
asign=powfunction(a,b);
printf("%d",asign%c);
}
}
I named it tt.c . when I tried to run the program writing gcc -o tt tt.c -lm in linux terminal it's giving the following output.
tt.c:9:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
9 | main()
| ^~~~
tt.c: In function ‘main’:
tt.c:15:12: warning: format ‘%lf’ expects argument of type ‘double *’, but argument 2 has type ‘double’ [-Wformat=]
15 | scanf("%lf %lf %d",a,b,c);
| ~~^ ~
| | |
| double * double
tt.c:15:16: warning: format ‘%lf’ expects argument of type ‘double *’, but argument 3 has type ‘double’ [-Wformat=]
15 | scanf("%lf %lf %d",a,b,c);
| ~~^ ~
| | |
| | double
| double *
tt.c:15:19: warning: format ‘%d’ expects argument of type ‘int *’, but argument 4 has type ‘int’ [-Wformat=]
15 | scanf("%lf %lf %d",a,b,c);
| ~^ ~
| | |
| int * int
pronay#MackbookPro:~$
After printing this the program is exited.
Any solution for this?
I used gcc -o tt tt.c -lm cmd to run it because someone said this is how to link the math library
The additional arguments should point to already allocated objects of
the type specified by their corresponding format specifier within the
format string.
You are passing the variables by value to scanf. However scanf expects pointers to the variables. You need to do this instead:
#include <stdio.h>
#include <math.h>
double powfunction (double x, double y)
{
double answer = pow(x,y);
return answer;
}
main()
{
int t, result, c, asign;
double a, b;
scanf("%d",&t);
for(t;t>0;t--){
//pass pointers to a, b, c instead
scanf("%lf %lf %d",&a,&b,&c);
asign=powfunction(a,b);
printf("%d",asign%c);
}
}
Also the main function should have this signature
int main(int argc, char *argv[])
or
int main(void)
and should return an integer value. If it does not, the return value is assumed to be 0.
#include <stdio.h>
int arredonda (double x)
{
int arredondado;
if (x - (int)x >= 0.5)
arredondado = (int)x + 1;
else
arredondado = (int)x;
return arredondado;
}
int main()
{
double num;
scanf("%f", &num);
printf("%d", arredonda(num));
return 0;
}
This is a function that rounds a number to upper or to lower depending of the decimal part. The problem is that it keeps returning 0 with all values.
%lf must be used to input a double.
Make sure to enable your compiler's warnings!
a.c: In function ‘main’:
a.c:16:13: warning: format ‘%f’ expects argument of type ‘float *’, but argument 2 has type ‘double *’ [-Wformat=]
scanf("%f", &num);
~^ ~~~~
%lf
I use -Wall -Wextra -pedantic with gcc and clang.
As for the rounding itself, there is a better solution: round from math.h.
This question already has answers here:
Printing int as float in C
(7 answers)
Closed 1 year ago.
#include <stdio.h>
#include <math.h>
int main(void)
{
float a = 16777215;
int b = pow(2, 26);
float c = 22345678;
printf("%f\n", a);
printf("%f\n", b);
puts("---------------");
printf("%f\n", c);
printf("%f\n", b);
return 0;
}
output:
16777215.000000
16777215.000000
---------------
22345678.000000
22345678.000000
why the former printf output can have influence to the subsequent printf output?
b isn't a float. Try %i for integer or %d for decimal.
#include <stdio.h>
#include <math.h>
int main(void)
{
float a = 16777215;
int b = pow(2, 26);
float c = 22345678;
printf("%f\n", a);
printf("%i\n", b);
puts("---------------");
printf("%f\n", c);
printf("%i\n", b);
return 0;
}
You need to match the type or strange things can happen:
printf("%d\n", b);
Compiling the original code with clang gives helpful warnings:
pow.c:10:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
printf("%f\n", b);
~~ ^
%d
pow.c:13:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
printf("%f\n", b);
~~ ^
%d
varargs functions like printf have a hard time pinning down their type requirements, it's up to compilers like clang to go the extra mile and show hints like this. You'll need to be extra careful when calling functions of that sort and be sure you're doing it precisely as documented.
As to how this ended up happening, it's not clear, but it doesn't have to be. Undefined behaviour is just that: Anything can happen. It could print the same thing. It could work. It could crash. There doesn't have to be an explanation.
Undefined behavior as you try to print integer with %f
Try
printf("%d\n", b);
To answer your specific question, my guess is that, at the assembly level, if the conversion is not correctly indicated, it will jump to ret, using the value previously stored in eax register.