As far as I can tell the logic in this makes sense. Yet the output is incorrect and I can seem to make sense of it.
#include <stdio.h>
int gcd(int, int);
int main()
{
int n, m;
printf("enter two numbers");
scanf("%d%d", &n, &m);
printf("The gcd of %d and %d is: %d \n", n, m, gcd(n,m));
return 0;
}
int gcd(int x, int y)
{
while(x!=y){
if(x>y)
return (x-y,y);
else
return(x,y-x);
}
return x;
}
That's not a recursive implementation of gcd, the function is not calling itself and besides it's using a while loop. A truly recursive approach will look like this:
int gcd(int x, int y) {
if (y == 0)
return x;
else
return gcd(y, x % y);
}
Or a bit shorter:
int gcd(int x, int y) {
return y == 0 ? x : gcd(y, x % y);
}
The above implementation is based on the Euclidean algorithm, refer to this for more details.
return (x-y,y);
will simply return y. That code compiles, but probably does not what you expected.
A non-recursive Euclid GCD algorithm would look like this:
int gcd (int x, int y)
{
while (y != 0)
{
int r = x % y;
x = y;
y = r;
}
return x;
}
Compared with a recursive version :
int gcd (int x, int y)
{
return y == 0 ? x : gcd (y, x%y);
}
As always in these trivial examples, the recursive approach uses less source code but is inefficient.
Copies of x and y plus the return address are passed on the stack, while the linear version simply works with an intermediate variable r for the remainder of x / y.
Even if some compilers might be smart enough to detect the unnecessary recursion and optimize it away, I think it is useful to understand the inherent cost of recursive coding.
Related
I'm new to C and I'm having some problems in this code where I'm getting these errors.
sum2.c: In function 'main':
sum2.c:22:6: warning: 'z' is used uninitialized in this function [-Wuninitialized]
int z = twice(x, z);
On my code I needed to add a fuction twice, which, given a number, calculates its double, using only the elementary operations and the sum function. And I don't know if the way I put the function is correct.
//USER
//3532
#include <stdio.h>
int sum(int x, int y){
return y == 0 ? x : sum(x+1, y-1);
}
int twice(int x, int z){
z = x * x;
return 0;
}
int main(void){
int x;
int y;
scanf("%d%d", &x, &y);
int z = twice(x, z);
printf("%d\n", z);
return 0;
}
The instructions say that twice is "given a number", but you've defined it as taking two numbers. It only needs one parameter.
And you're supposed to use your sum() function. There's no need to multiply x*x (that's the square of the number, not twice the number), nor is there any point in assigning a variable in the return statement.
You only need to read one number as input to test this.
#include <stdio.h>
int sum(int x, int y)
{
return y == 0 ? x : sum(x+1, y-1);
}
int twice(int x)
{
return sum(x, x);
}
int main(void)
{
int x;
int w;
scanf("%d", &x);
int w = twice(x);
printf("%d\n", w);
return 0;
}
According to your description the function twice should accept only one argument.
So this function definition
int twice(int x, int z)
{
z = x * x;
return 0;
}
does not make sense. Moreover the function always returns 0.
Also take into account that the type int is a signed integer type. The user can input a negative number. In this case your function sum will yield a wrong result.
The sum of two integers of the type int can be too big to fit in an object of the type int. That is there can be for example an overflow.
The functions can be defined the following way as it is shown in a demonstrative program.
#include <stdio.h>
long long int sum( int x, int y )
{
return y == 0 ? ( long long int )x
: sum( y < 0 ? x - 1 : x + 1, y < 0 ? y + 1 : y - 1 );
}
long long int twice( int x)
{
return sum( x, x );
}
int main(void)
{
int x;
printf( "Enter a number: " );
scanf("%d", &x);
long long int result = twice( x );
printf("The sum is %lld\n", result );
return 0;
}
Its output might look like
Enter a number: -5
The sum is -10
Or
Enter a number: 5
The sum is 10
so I have to write a recursive algorithm for exponentiation and I have to use this to make the algorithm faster: and then I'd have to figure out how many time multiplication is happening. I wrote it, but I am not sure if I am right - also I need some help with figuring out the multiplication part.
#include <stdio.h>
#include <math.h>
double intpower(double x, int n)
{
double result;
if(n>1&&n%2!=0) {result=x*intpower(x,(n-1)/2)*intpower(x,(n-1)/2);}
if(n>1&&n%2==0) {result=intpower(x,n/2)*intpower(x,n/2);}
if(n==1) return x;
else return result;
}
int main()
{
int n;
double x,result;
printf("x\n");
scanf("%lf", &x);
printf("n\n");
scanf("%d", &n);
printf("result = %.2f\n", intpower(x,n));
return 0;
}
The inductive definitions are saying
If k is even, then x^k = [ x^(k/2) ] ^ 2
If k is odd, then x^k = x * [ x^(floor(k)/2) ] ^ 2
With these it's a bit easier to see how to arrange the recursion:
#include <stdio.h>
double int_pwr(double x, unsigned k)
{
if (k == 0) return 1;
if (k == 1) return x; // This line can be omitted.
double y = int_pwr(x, k/2);
return (k & 1) ? x * y * y : y * y;
}
int main(void)
{
double x;
unsigned k;
scanf("%lf%u", &x, &k);
printf("x^k=%lg\n", int_pwr(x, k));
return 0;
}
I've changed types to be a bit more logical and saved an exponential (in k) amount of work that the OP's solution does by making two recursive calls at each level.
As to the number of multiplications, it's pretty easy to see that if k's highest order bit is 2^p (i.e. at position p), then you'll need p multiplications for the repeated squarings. Another way of saying this is p = floor(log_2(k)). For example if k=4=2^2, you'll square the square to get the answer: 2 multiplications. Additionally you'll need q-1 more, where q is the number of 1's in k's binary rep. This is the number of times the check for "odd" will be true. I.e. if k = 5 (which has 2 bits that are 1's), you'll square the square and then multiply the result by x one more time. To summarize, the number of multiplications is p + q - 1 with p and q as defined above.
To figure out how many times multiplication is happening, you could count them in intpower().
static int count = 0;
double intpower(double x, int n) {
double result;
if(n>1&&n%2!=0) {result=x*intpower(x,(n-1)/2)*intpower(x,(n-1)/2); count += 2;}
if(n>1&&n%2==0) {result=intpower(x,n/2)*intpower(x,n/2); count++;}
if(n==1) return x;
else return result;
}
int main() {
int n;
double x,result;
printf("x\n");
scanf("%lf", &x);
printf("n\n");
scanf("%d", &n);
mcount = 0;
printf("result = %.2f\n", intpower(x,n));
printf("multiplcations = %d\n", mcount);
return 0;
}
Try this
double intpower(double x, int n)
{
if(n == 0) return 1;
if(n == 1) return x;
if(n%2!=0)
{
return x*intpower(x,(n-1));
}
else
{
x = intpower(x,n/2);
return x*x;
}
}
or you can reduce your function to one line
double intpower(double x, int n)
{
return n == 0 ? 1 : n%2 != 0 ? x*intpower( x, (n-1) ) : (x = intpower(x, n/2), x*x);
}
I'm trying to write a code that will take x as input and give cos(x) as output, using maclaurin's series.I'm using a while loop until the difference of two consecutive results is less then 0.001. I'm using double type to accomodate larger values.
the code works when x is in range [-2,2], but if x is greater or less than this range the ouput is -1.#IND00. Why is it happening? is the output value out of range ? how can i fix this ??
my code is :
#include <stdio.h>
double abs(double a);
double power(double p, int q);
int fact(int a);
int main()
{
int i=1,j=2*i;
double x,s=1.0,p,l=0.001;
printf("Enter x: ");
scanf("%lf", &x);
p = s+ power(-1,i) * power(x,j) / fact(j);
while (abs(p-s)>l){
i++; j=2*i;
s=p;
p = s+ power(-1,i) * power(x,j) / fact(j);
}
printf("cos(%f) = %f", x,p);
return 0;
}
double abs(double a)
{
if (a>=0) return a;
else return (-a);
}
double power(double p, int q)
{
int i;
double a=1.0;
for (i=0; i<q; i++){
a=a*p;
}
return a;
}
int fact(int a)
{
int i,p=1;
if (a==0 || a==1) return 1;
else
while (a!=1){
p=p*a;
a--;
}
return p;
}
update your scanf function to
scanf("%lf", &x);
Also you need to check pow and fact, these functions could overflow. Especially, fact which only use int.
As a larger |x| is use, more terms are needed and fact() overflows and strange results follow. Use double.
// int fact(int a)
double myfact(double p, int q) {
int i;
double a = 1.0;
for (i=0; i<q; i++){
a=a*p;
}
return a;
}
Eventually with values somewhere larger |x| > 30, other limitations kick in using this method. The limitation is due to precision and not range. For large values a significantly different algorithm should be used.
Potential conflict between int abs(int j) in <stdlib.h>. The prototyped may be found via stdio.h and conflicts with OP double abs(double a). In any case, abs() is a standard library function and OP should avoid that function name. Also recommend renaming power().
// double abs(double a)
double myabs(double a)
So I had to write a program that used the Pythagorean Threes concept where if you entered a number it would give you all the combinations less than that number that would produce a correct a^2 + b^2 = c^2 output.
Not sure if I explained the assignment well, but basically I understand the logic or at least I think I do I was wondering if you guys could help me find out why I am getting this error....
For the last line of my code it gives me, "warning: control reaches end of non-void function [-Wreturn-type]," As the error any idea what I am doing wrong?
#include <stdio.h>
int main(void){
int x = 0, y = 0, z = 0, n;
int count = 0;
printf("Please Enter A Positive Integer: \n");
scanf("%d", &n);
while(z <= n){
while(y < z){
while(x < y){
if(x * x + y * y == z * z)
printf("%d: \t%d %d %d\n", ++count, x, y, z);
x += 1; }
y += 1; }
z += 1;
}
}
int main(void){
Your function header indicates that you're looking to return an int. To fix this, return a number (0 usually indicates a normal termination) at the end of your function.
To break it down a little,
int indicates the return type,
main is the method name, and
void indicates that there are no parameters for this method.
Your main function is declared to return an int, but you don't return anything.
put return 0; before the closing brace of your main.
int main( void )
{
// ... code ...
return 0;
}
gcd should be a recursive function. It should return void. It should take two positive integers and place the GCD in the third parameter.
Here is my coded gcd function. However, I realized that it is not a recursive function. How would I change this code so it is a recursive function?
void gcd(int *x, int *y) {
int i;
getValuesForGCD(x, y);
for (i = *x; i >= 1; i--)
{
if (*x % i == 0 && *y % i == 0)
{
printf("The GCD of %d and %d is %d", *x, *y, i);
break;
}
}
}
GCD is naturally defined as a recurrent formulae. It's straightforwardly transformed into a recursive function:
gcd(a, 0) = a
gcd(a, b) = gcd(b, a % b)
Write this in a C format and that's it.
int gcd(int a, int b) {
if (b == 0)
then return a
else return gcd(b, a % b);
}
You should notice that a and b must be non-negative number.
and the nice thing is, this is a tail-recursion, so it run as fast as non-recursive method.
Normally, people work to remove recursion, not introduce it.
If you want a literal conversion of your iterative algorithm to recursive, it would go like this:
void gcdrecursive(int *x, int *y, int i)
{
if (i >= 1) {
if (*x % i == 0 && *y % i == 0) {
printf("The GCD of %d and %d is %d", *x, *y, i);
} else {
gcdrecursive(x, y, i - 1);
}
}
}
void gcd(int *x, int *y) {
getValuesForGCD(x, y);
gcdrecursive(x, y, *x);
}
To convert an iterative solution to recursive, you convert each loop to a recursive function that performs one iteration of the loop, then calls itself recursively for the next iteration. Breaking the loop corresponds to stopping the recursion. In your example, the loop breaks for two reasons: Either the GCD is found or i reaches zero.
Note that this is not the best algorithm for gcd, but it takes the function you provided and converts it to recursive, as requested.