can't implement any series that uses power or factorial - c

I wrote a program to calculate the value of e^x by series and by library function.See the following:
#include<stdio.h>
#include<math.h>
long long fact(int x)
{
long prod=1;
int i=1;
if(x==0)
return 1;
else{
while(i<=x)
{
prod=prod*i;
i++;
}
return prod;
}
}
int main()
{
int i;
float x;
double sum=1;
for(x=1;x<20;x++)
{
for(i=1;i<=10;i++)
{
if(fact(i)!=0);
sum=sum+pow(x,i)/fact(i);
}
printf("by code e=%.15lf\t\t",sum);
printf("by libfnc e=%.15f\t",exp(x));
printf("quotient =%.15f\n",sum/exp(x));
}
}
The code works for smaller values like 1,2 but with the increase of the value of x the difference (here quotient) increases.That is my code no longer gives correct answer for higher values of x.

You need function prototype before calling it.
Add some ifs to check if you do not divide by zero.
scanf returns number of successfully scanned elements. Check for 1 in this case.
int fct = fact(2*i);
if(fct)
sum=sum+y/(double)fct;
else
{printf("DIVISION BY ZERO!!!!\n"); return 1;}
You will discover that int is to small for factorial function. Change it to double. Also, use double in all floating point operations.
double fact(int x);
int main()
{
double sum,y;
int x,i=0;
double fct;
while(scanf("%d",&x) == 1)
{ sum=0;
for(i=0;i<=N;i++)
{
y=pow(-1,i)*pow(x,2*i);
fct = fact(2*i);
if(fct != 0.0)
sum=sum+y/fct;
else
{printf("DIVISION BY ZERO!!!!\n"); return 1;}
}
printf("using Maclaurin's series %.10f and original cosx=%.10f",sum,cos(x));
}
}
double fact(int x)
{
double prod=1.0;
int i=1;
for(i=1;i<=x;i++)
prod=prod*i;
return prod;
}
https://godbolt.org/z/qsh4qh3d1

Related

Write a C function to evaluate the series // sin(x) = x-(x3 /3!)+(x5 /5!)-(x7 /7!)+... // up to 10 terms

#include <stdio.h>
#include<math.h>
int series(float,float);
int main()
{
float x,n,series_value;
printf("Enter the value of x: ");
scanf("%f",&x);
printf("\nEnter the value of n: ");
scanf("%f",&n);
series_value=series(x,n);
printf("\nValue of series sin (%.2f) is: %f\n",x,series_value);
return 0;
}
int series(float x,float n)
{
int i,sum=0,sign=-1;
int j,fact=1,p=1;
for (i=1; i<=(2*n)-1; i+=2)
{
for (j=1; j<=i; j++)
{
p=p*x;
fact=fact*j;
}
sign=-1*sign;
sum=sum + sign*p/fact;
}
return (sum);
}
Output:
Enter the value of x: 5
Enter the value of n: 10
(lldb)
and this message
Thread 1: EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)
![Thread 1 Queue : com.apple.main-thread (serial)
]1
Why is this message coming? and what is wrong in the program as answer is not coming right
There is a few problems with your code. As #PaulHankin said, when fact overflows and becoms zero, you will have a division by zero, and "weird things" happen.
Your factorial and power calculation is also wrong. You are recalculating it in each iteration of the outer loop without reseting fact and p first:
fact = 1; // You need to reset fact and p to its start value here
p = 1;
for (j=1; j<=i; j++)
{
p=p*x;
fact=fact*j;
}
Your third problem is that for your function calculate the correct value for sin, which is not an integer value, you need to use float, or even better double, when calculating sum. So sum must be declared float, and the division p/fact must use float division. By also declaring p and fact as float, you will solve both the overflow issue, and use the correct division. Naturally your function must also return a float
float series(float x,float n)
{
int i,sign=-1;
int j,
float sum = 0;
float fact = 1;
float p = 1;
for (i=1; i<=(2*n)-1; i+=2)
{
fact = 1;
p = 1;
for (j=1; j<=i; j++)
{
p=p*x;
fact=fact*j;
}
sign=-1*sign;
sum=sum + sign*p/fact;
}
return (sum);
}
This code still has a minor problem. By having an inner loop, it is slower than necessary. Since this probably is homework, I am not getting rid of that loop for you, just giving you a hint: You don't have to recalculate fact from scratch on each iteration of the outer loop, just try to find out how fact changes from one iteration to the next. The same goes for p.
//Series of Sinx
#include<stdio.h>
#include<math.h>
#define ACCURACY 0.0001
int factorial(int n);
int main()
{
float x,sum,term;
int i,power;
printf("Enter value of X: ");
scanf("%f",&x);
i=1;
power=3;
sum=x;
term=x;
while(term>=ACCURACY)
{
term = pow(x,power) / factorial(power);
if(i%2==1)
{
sum -= term;
}
else
{
sum += term;
}
power+=2;
i++;
}
printf("sin(%f) = %.6f\n",x,sum);
return 0;
}
int factorial(int n){
int i=n,fact=1;
for(i=1;i<=n;i++)
{
fact=fact*i;
}
return fact;
}
plenty bugs. To do not caclulate the fact values all the time they are in the lookup table
#include <stdio.h>
#include <math.h>
double series(double,int);
long long fact[] = { 1, 2, 6, 24,
120, 720, 5040, 40320,
362880, 3628800, 39916800, 479001600,
6227020800, 87178291200, };
double mypow(double x, unsigned p)
{
double result = x;
while(p && --p)
result *= x;
return result;
}
int main()
{
for(double x = 0; x <= M_PI + M_PI / 60; x += M_PI / 30)
printf("Value of series sin (%.2f) is: %f\n",x,series(x, 5));
fflush(stdout);
}
double series(double x,int n)
{
double sum = x;
int i,sign=1;
for (i=3; i<=(2*n)-1; i+=2)
{
sign=-1*sign;
sum += sign*(mypow(x, i)/fact[i -1]);
}
return (sum);
}
https://godbolt.org/z/U6dULN
maybe its due to floating-point exception as u have declared that the function should return int type value
int series(float,float);//hear
so u can try editing the return type of this function as float
Note:-also u need to change at function definition and the datatype of
int i,sum=0,sign=-1;
int j,fact=1,p=1;
to float as it is returning the value (sum) which should also be float

This code show error. Could you teach me what is the error is and how to change it?

ERRRO CODE (advancedpower function)
When I operate this code and write the input, the output is wrong.
use : ln(x), e^x
consider when a == 0
x can be positive, negative, or zero or any fractional number
if a==0 -> a^x=0
a^x=advancedpower(ln(exp(power(a^x)))
#include <stdio.h>
#include <assert.h>
int factorial(int x)
{
if(x>0)
{
return (x*factorial(x-1));
}
if(x==0)
{
return 1;
}
else
return 0;
}
float power(float x, float y)
{
float r;
r=1.0;
if (x==0)
{
return 0;
}
if (y==0&& x!=0) {
return 1;
}
else
for(int i=1; i<=y;i++) {
r=r*x;
}
return r;
}
float exp(float x){
float sum=1.0;
for (int i = 0;i<10; i++) {
sum = sum + (power(x,i)/factorial(i));
}
return sum;
}
float ln(float x)
{
assert(x > 0);
float o= 1.0;
for (int i = 1;; i++) {
int k = 2*i-1;
float t = 2.0* power((x-1)/(x+1),k)/k;
o=o+t;
}
return o;
}
float advancedpower(float n1,float n2){
if (n1 ==0){
return 0;
}
else
return (exp(power(n1,n2)));
}
int main()
{
float a, x;
scanf("%f%f", &a, &x);
printf("%.4f", advancedpower(a, x));
return 0;
}
input 2.0 0.5
output 1.4142
however when I enter 2.0 0.5, the output is 3.7183
What should I have to change.....
With the input “2.0 0.5”, a is set to 2, and x is set to .5. Then advancedpower is called with arguments 2 and .5. In turn, advanceddpower calls power, also with arguments 2 and .5.
power is a recursive function. When x and y are not zero, it calls power(x, y - 1). This results in calling power with arguments 2 and −.5. Then it executes the same code again, which calls power with arguments 2 and −1.5. Then again with 2 and −2.5. This continues until the stack is exhausted, and the program crashes.
This code has not been written to handle these values. You need to rethink the design.

C Power function negative exponent without pow()

I'm trying to make a little power calculator for learning purposes in C without using pow,
but it always returns 0.00 when exponent is negative, please help.
full code:
#include<stdio.h>
//* power caculator function
int power(x,y)
{
float p=1.00;
int i;
if (y<0){
y=-1*y;
x=1/x;
}
for (i=1;i<=y;i++)
{
p=p*x;
}
return p;
}
//* main gets input, calls power caculator and prints result'
int main()
{
int b;
int e;
float p;
printf("enter base");
scanf("%d",&b);
printf("enter exponent");
scanf("%d",&e);
p=power(b,e);
printf("%d to the power of %d is %.2f",b,e,p);
return 0;
}
//* I am NOOB
You are using integers to hold decimal values, in this case with x and with the return type of the power function.
try:
float power(x,y)
{
float p=1.00;
float xx = (float)x;
int i;
if (y<0){
y=-1*y;
xx=1/xx;
}
for (i=1;i<=y;i++)
{
p=p*xx;
}
return p;
}
define data types of x and y explicitly and then adjust the return data type.

Numerical Integration, using the trapezium rule in C

I am using the trapezium rule to calculate the integral of a function between 0 and infinity. I can calculate the value of the integral for a given value of N, and now I am trying to loop N from two to a given value but it will not work. It keeps calculating the value of the integral for when N is 2 and repeating instead of the new value of N. The problem is in the for loop in main() I think.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
double f(double x) {
double a;
a =1/((1+x)*pow(x,0.5));
return a;}
double tra(double upper, double lower, int N) {
double sum, step, integral,lowest;
step=(upper-lower)/(N-1);
lower=lower+step;
if(lower==0) {
lowest=DBL_EPSILON;}
else {
lowest=lower;}
while(lower<upper) {
sum=sum+f(lower);
lower=lower+step;}
integral=step*(sum+(f(upper)/2)+(f(lowest)/2));
sum=0;
return integral;}
main() {
int N;
double upper=DBL_EPSILON*2, lower=0, total=0;
for(N=2;N<20000;N+=100) { /*Here im trying to loop N so that the integral is calculated for increasing values of N*/
while(upper<FLT_MAX) {
total=total+tra(upper, lower, N);
lower=upper;
upper=upper*2;}
printf("Integral is %.10f\n", total);
}
}
I suggest you move the variable initialisation to within the for loop like this:
int main(void) {
int N;
double upper, lower, total;
for(N=2;N<20000;N+=100) {
upper = DBL_EPSILON*2;
lower = 0;
total = 0;
while(upper<FLT_MAX) {
total=total+tra(upper, lower, N);
lower=upper;
upper=upper*2;
}
printf("Integral is %.10f\n", total);
}
return 0;
}

-1.#IND00 output for certain input values

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)

Resources