How to fix unexpected output in recursive C program? - c

I am attempting to write a simple recursive function to evaluate Associated Legendre Polynomials in C. As of now, I only have it written up to L=4 and M=3. I am using the seventh recurrence formula from the following Wikipedia article:
https://en.wikipedia.org/wiki/Associated_Legendre_polynomials
Here is my code:
#include <stdio.h>
#include <math.h>
long double Legendre(int L, int M, double x){
if((M == 0) && (L == 0)){
return 1;
}
if((M == 0) && (L == 1)){
return x;
}
if((M == 0) && (L == 2)){
return (1/2) * ((3*x*x) - 1);
}
if((M == 0) && (L == 3)){
return (1/2) * ((5*pow(x,3)) - (3*x));
}
if((M == 0) && (L == 4)){
return (1/8) * (3 - (30*x*x) + (35*pow(x,4)));
}
else if(M > 0){
return (((L - M + 1)*x*Legendre(L,M-1,x))
- ((L + M - 1)*Legendre(L-1,M-1,x)))
/ sqrt(1-(x*x));
}
return 0;
}
int main(void){
int L = 4;
int M = 2;
double x = 0.6;
printf("%Lf\n",Legendre(L,M,x));
}
As per Mathematica, the Associated Legendre Polynomial with L=4, M=2, and x=0.6 should be 7.3. However, when I run the above program, I get the following result:
$ gcc Rodrigues.c -o Rodrigues
$ ./Rodrigues
0.000000
$
(My source file name is Rodrigues.c). The output should be around 7.3, not 0. The code also produces other non-zero (though still incorrect) values for different Ls and Ms. I am suspecting it is because I have somehow messed up the recursion (as you can tell, I am relatively new to programming). What am I missing? Thanks.

Related

CS50 Credit Assignment - Floating Point Exception

any ideas why this is generating a floating point exception? Please ignore the bad coding. This is very rough and I am just trying to experiment different things on this assignment. Also, I trying to do this assignment with only the operations learned in class (I am awere there are others that would make this easier)
Thanks!
#include <stdio.h>
#include <cs50.h>
int main(void)
{ long c = get_long("What is your credit card number?\n");
long i = 10;
long j = 100;
long n = 0;
long m = 0;
long x = 2;
do
{ long a = (c % i - (c % i)/10)/(i/10);
n = a + n;
i = i*100;
}
while (c/i >= 0.1 || c/i == 0);
do
{ long b = (c%j - (c%j)/10)/(j/10);
m = b + m;
j = j*100;
}
while (c/j >= 0.1 || c/j == 0);
long sum = n + 2*m;
if (i > j)
{
x = i;
}
else
{
x = j;
}
if (sum % 10 == 0)
{ if((x == 10000000000000000) && ((c % (x/100) - c % (x/1000))/(x/100000) == (34)))
{
printf("Amercan Express\n");
}
else if((x == 100000000000000000) && ((c % (x/100) - c % (x/1000))/(x/100000) == (51)))
{
printf("MasterCard\n");
}
else if((x == 10000000000000) && ((c % (x/100) - c % (x/1000))/(x/100000) == 4))
{
printf("Visa\n");
}
else if((x == 10000000000000000) && ((c % (x/100) - c % (x/1000))/(x/100000) == 4))
{
printf("Visa\n");
}
else
{
printf("Invlid\n");
}
}
else
{
printf("Invlid\n");
}
}'''
This is the part that is the problem:
while (c/i >= 0.1 || c/i == 0);
in your first do while loop.
Your data types are long and so you are saying that as long as c/i is greater than 0.1 or == 0 then keep going. Unfortunately this will go on forever as a long will always be >= 0.1 or <= 0 because it cant hold decimal places.If you play around with debug50 by using debug50 ./filename you can place a red dot and step through. What you will see is the first do while loop will keep running increasing the value of i every cycle. Eventually the value of i is bigger than the memory limit for a long and so the code creates unexpected results.If you step through you find that it eventually assigns 0 to i and so you suffer a divide by 0 error.
You can fix this by changing data types or altering that while loop.
I hope that helps. Id suggest stepping through that do while loop using debug50 in the cs50 ide to see whats going on.

Understanding calling one function inside another C

I'd like to ask the following misunderstandings of C language, which I see I'm having.
I'm sorry if the code is not properly indented, I tried as much as I could but there are not so many guides on the internet.
The program asked given a starting number 'val' and a Even-Odd or Odd-Even alternating sequence (which stops whenever this rules is violated) to print the greater prime number with 'val'.
I tried with two functions and the main: one to control the GCD between two given numbers and the other to keep tracks of the greatest one, but I think I miss something in the code or in the conception of C function,
Because when compiled it returns me 0 or great number which I'm not entering.
One example to understand what I should do:
If my sequence was 10, 7, 8, 23 and my val was 3, I had to print 23, because it is the greatest integer prime with 3.
Here's the code :
#include <stdio.h>
int mcd(int a, int b)
{ // Gcd function
if (a == 0)
return b;
else
return mcd(b % a, b);
}
int valuta(int val, int h) // Valuing Max function
{
int temp = 0;
if (mcd(val, h) == 1 && h > temp)
temp = h;
return temp;
}
int main()
{
int val, d, x, y, z, t, contatore = 1;
scanf("%d", &val);
scanf("%d%d", &x, &y);
if (x > y && mcd(val, x) == 1)
{ // Two options
t = x;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
}
if ((x % 2 == 0 && y % 2 == 0) || (x % 2 == 1 && y % 2 == 1))
{ // Bad case
if (x > y && mcd(val, x) == 1)
{
t = x;
contatore = 0;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
contatore = 0;
}
}
else
{
while (contatore == 1)
{
scanf("%d", &z);
t = valuta(val, z);
if (x % 2 == 0 && z % 2 == 0)
{ // Even- Odd - Even
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 0)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
if (x % 2 == 1 && z % 2 == 1)
{ //Odd- Even- Odd
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 1)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
}
}
printf("%d\n", t);
return 0;
}
PS. Is there any way to reduce the number of lines of code or to reduce the effort in coding? I mean, a straightforward solution will be helpful.
Your valuta() function is flawed in that it needs to return the maximum qualifying value so far but has no knowledge of the previous maximum - temp is always zero. The following takes the previous maximum as an argument:
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) == 1 && h > previous ) ? h : previous ;
}
And is called from main() thus:
t = valuta( val, x, t ) ;
The test mcd(val, h) == 1 is flawed, because mcd() only ever returns the value of parameter b which is not modified in the recursion, so will never return 1, unless the argument b is 1. Since I have no real idea what mcd() is intended to do, I cannot tell you how to fix it. It appear to be a broken implementation of Euclid's greatest common divisor algorithm, which correctly implemented would be:
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
But I cannot see how that relates to:
"[...] he greatest integer prime with 3 [...]
The odd/even even/odd sequence handling can be drastically simplified to the extent that it is shorter and simpler than your method (as requested) - and so that it works!
The following is a clearer starting point, but may not be a solution since it is unclear what it is it is supposed to do.
#include <stdio.h>
#include <stdbool.h>
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) && h > previous ) ? h : previous ;
}
int main()
{
int val, x, t ;
printf( "Enter value:") ;
scanf("%d", &val);
typedef enum
{
EVEN = 0,
ODD = 1,
UNDEFINED
} eOddEven ;
eOddEven expect = UNDEFINED ;
bool sequence_valid = true ;
printf( "Enter sequence in odd/even or even/odd order (break sequence to exit):\n") ;
while( sequence_valid )
{
scanf("%d", &x);
if( expect == UNDEFINED )
{
// Sequence order determined by first value
expect = (x & 1) == 0 ? EVEN : ODD ;
}
else
{
// Switch expected odd/even
expect = (expect == ODD) ? EVEN : ODD ;
// Is new value in the expected sequence?
sequence_valid = (expect == ((x & 1) == 0 ? EVEN : ODD)) ;
}
// If the sequence is valid...
if( sequence_valid )
{
// Test if input is largest qualifying value
t = valuta( val, x, t ) ;
}
}
// Result
printf("Result: %d\n", t);
return 0;
}

Binomial coefficient recursive function in C - brings wrong result, why?

beginner here trying to understand the source of the bug.
I have written this recursive function for finding the binomial coefficient between two numbers which is apparently correct in concept. However, for these two numbers, n =4 and k=2, I should be getting 6 as a result whereas I actually get 16. Any idea why is that happening?
#include<stdio.h>
int binomial(int n, int k)
{
if ((k = 0) || (k == n))
return 1;
if (k>n)
return 0;
return binomial(n - 1, k - 1) + binomial(n - 1, k);
}
int main()
{
int a, b, res;
a = 4;
b = 2;
res = binomial(a, b);
printf("The result is %d", res);
return 0;
}
This line looks wrong as it assigns 0 to k:
if ((k=0) || (k==n))
You probably mean:
if ((k==0) || (k==n))
This line
if ((k = 0) || (k == n))
should be
if ((k == 0) || (k == n))
^^
You were assigning zero to k.
As #Michael Walz points out, it's good practice to compile with -Wall to turn on all compilation warnings.

Program for finding nth root of the number without any external library or header like math.h

Is there any way to find nth root of the number without any external library in C? I'm working on a bare metal code so there is no OS. Also, no complete C is there.
You can write a program like this for nth root. This program is for square root.
int floorSqrt(int x)
{
// Base cases
if (x == 0 || x == 1)
return x;
// Staring from 1, try all numbers until
// i*i is greater than or equal to x.
int i = 1, result = 1;
while (result < x)
{
if (result == x)
return result;
i++;
result = i*i;
}
return i-1;
}
You can use the same approach for nth root.
Here there is a C implementation of the the nth root algorithm you can find in wikipedia. It needs an exponentiation algorithm, so I also include an implementation of a basic method for exponentiation by squaring that you can find also find in wikipedia.
double npower(double const base, int const n)
{
if (n < 0) return npower(1/base, -n)
else if (n == 0) return 1.0;
else if (n == 1) return base;
else if (n % 2) return base*npower(base*base, n/2);
else return npower(base*base, n/2);
}
double nroot(double const base, int const n)
{
if (n == 1) return base;
else if (n <= 0 || base < 0) return NAN;
else {
double delta, x = base/n;
do {
delta = (base/npower(x,n-1)-x)/n;
x += delta;
} while (fabs(delta) >= 1e-8);
return x;
}
}
Some comments on this:
The nth root algorithm in wikipedia leaves freedom for the initial guess. In this example I set it up to be base/n, but this was just a guess.
The macro NAN is usually defined in <math.h>, so you would need to define it to be suitable for your needs.
Both functions are implemented in a very rough and simple way, and their performance can be greatly improved with careful thought.
The tolerance in this example is set to 1e-8 and should be changed to something different. It should probably be proportional to the value of the base.
You can try the nth_root C function :
// return a number that, when multiplied by itself nth times, makes N.
unsigned nth_root(const unsigned n, const unsigned nth) {
unsigned a = n, b, c, r = nth ? n + (n > 1) : n == 1 ;
for (; a < r; b = a + (nth - 1) * r, a = b / nth)
for (r = a, a = n, c = nth - 1; c && (a /= r); --c);
return r;
}
Source

How does recursive function in C works

Function fun(n) is defined as such:
fun(n) = 1 (if n <=1)
fun(n) = fun(n/2) (if n is even)
fun(n) = 2*fun((n-1)/3) (if n> and n is odd)
I'm trying to write a recursive function to compute and return the result. I just started learning recursion, I got kind of lost while doing this function. Can someone correct me and explain to me? Thanks!
Here's what I did:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
int fun(int n);
int main()
{
int num;
printf("\nEnter a number: ");
scanf("%d", num);
printf("Result = %d\n", fun(num));
return 0;
}
int fun(int n)
{
if (n <= 1)
{
return 1;
}
else if (n % 2 == 0)
{
return fun(n / 2);
}
else if ((n > 1) && (n % 2 == 0))
{
return 2 * fun((n - 1) / 3);
}
}
Expected output:
Enter a number: 13
Result = 2
Enter a number: 34
Result = 4
Output I'm getting instead:
Enter a number: 13
Result = 1
Enter a number: 34
Result = 1
scanf takes a pointer to int as argument for %d, i.e.,
scanf("%d", &num);
Also, your function fun does not handle all cases and may fall off the bottom:
if (n <= 1)
{
return 1;
}
else if (n % 2 == 0)
{
return fun(n / 2);
}
else if ((n > 1) && (n % 2 == 0))
{
return 2 * fun((n - 1) / 3);
}
The last else if condition is never met, because the previous check for n % 2 == 0 already returns in that case. Also the n > 1 is pointless because the first n <= 1 returns in all other cases.
You can simply make it:
else
{
return 2 * fun((n - 1) / 3);
}
The culprit is the last else if condition. Change it to:
else if ((n % 2) != 0)
The condition that n is odd is written wrong here. You wrote the same thing as for when n is even.
Its probably better to explicitly make the cases disjoint so you always return and there's no warning, like this:
int fun(int n)
{
if(n <= 1)
return 1;
if(n % 2 == 0)
return fun(n/2);
//No need for a condition, we know the last one must be satisfied
return 2 * fun((n-1)/3);
}
or, add another "default" case that indicates there was some error.
I think last if should be:
else if ((n > 1) && (n % 2 != 0))
Notice the != instead of ==.
The third condition
else if ((n > 1) && (n % 2 == 0))
is wrong, but instead of fixing it just you else no else if - because all other conditions were checked already.

Resources