1

I am very new to C programming. Here, I have written a very simple C program to evaluate the Taylor series expansion of exponential function e^x, but I am getting error in my output, though the program gets compiled successfully.

#include <stdio.h>
int main()
{
double sum;
int x;
printf("Enter the value of x: ");
scanf("%d",&x);
sum=1+x+(x^2)/2+(x^3)/6+(x^4)/24+(x^5)/120+(x^6)/720;
printf("The value of e^%d is %.3lf",x,sum);
return 0;
}
Roshan Shrestha
  • 178
  • 2
  • 10
  • 3
    What xing said and you're using `int` for `x`. Make x double and use `pow(base,exp)` at this stage. – Persixty May 12 '17 at 10:54
  • @DanAllen Nah, `pow` is defined via Taylor series internally. The correct thing to use is [Horner's method](https://en.wikipedia.org/wiki/Horner%27s_method) – polkovnikov.ph May 12 '17 at 10:56
  • Possible duplicate of [Taylor series of function e^x](http://stackoverflow.com/questions/33333791/taylor-series-of-function-ex) – polkovnikov.ph May 12 '17 at 10:58
  • Don't think it's a duplicate since my method is only about evaluating the expression rather than using iteration – Roshan Shrestha May 12 '17 at 10:59
  • Can't we just modify the above code of mine rather than using iteration ? – Roshan Shrestha May 12 '17 at 11:00
  • 1
    Possible duplicate of [Why is my power operator (^) not working?](http://stackoverflow.com/questions/4843304/why-is-my-power-operator-not-working) – Martin R May 12 '17 at 11:09
  • 1
    @polkovnikov.ph We've got a real novice here. One step at a time. It's the accepted answer! – Persixty May 12 '17 at 11:25
  • @polkovnikov.ph The C standard says nothing about how `pow` is implemented internally. – Ian Abbott May 12 '17 at 14:37
  • @IanAbbott If you know another way to exponentiate with fractional power, I'll be glad to hear it. – polkovnikov.ph May 12 '17 at 15:29
  • @polkovnikov.ph I don't know of such a way, but I don't see why it can't just be treated as a black box function. Besides, `pow` only needs to be called with integer exponent in this case. – Ian Abbott May 12 '17 at 15:47
  • @IanAbbott Because it's at least 40 times slower than multiplication, for example. Learning C without learning underlying architecture leads to troubles when people get hired. Using `pow` instead of multiplication is a bug. Promoting usage of such code is braindead. – polkovnikov.ph May 12 '17 at 16:13
  • @polkovnikov.ph `pow` might be more accurate than repeated multiplication due to accumulated errors. – Ian Abbott May 12 '17 at 16:18
  • @IanAbbott Exactly! That's why you never write Taylor series by hand, and just use `exp(...)` – polkovnikov.ph May 12 '17 at 16:57

4 Answers4

4

^ in C is not an exponentiation operator. It is a bitwise operator. For a short number of terms, it is easier to just multiply.

You also need to take care of integer division. If you divide x*x/2, then you will get integer division. You need to divide the number to get a double answer, as shown below.

You can replace the line calculating the sum with the following line.

sum=1+x+(x*x)/2.0+(x*x*x)/6.0+(x*x*x*x)/24.0+(x*x*x*x*x)/120.0+(x*x*x*x*x*x)/720.0;

A better option would be to use a loop to calculate each term and add it to the answer.

double answer, term = 1;
int divisor = 1;
amswer = term;
for (i=0; i<6; i++)
{
   term = term * x / divisor;
   answer += term;
   divisor *= (i+2);
}   
Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
  • `divisor` can be a `double` too. Otherwise there might be a type conversion each time `term = term * x / divisor` is executed - need to check the asm output though. – u354356007 May 12 '17 at 11:10
  • `divisor` can be an integer as long as it does not go out of range. For a 32 bit integer it will work upto 12 terms. If you use a `unsigned long long int` it will work upto 20 terms. The division each term is between a double and an int which will resolve into a double. – Rishikesh Raje May 12 '17 at 11:54
  • No, the previous commenter was talking about implicit conversion of `int` to `double` when you're calling `... / divisior`. Such conversions are pretty slow. – polkovnikov.ph May 12 '17 at 16:23
  • Also your braces are not K&R, you have extraneous parentheses around `i + 2`, and proper loop clause should've been `for (int i = 0; i < 6; ++i) {` – polkovnikov.ph May 12 '17 at 16:26
3
  1. Use pow() instead of ^
  2. Use double x instead of int x

So the result code will look like:

#include <stdio.h>
#include <math.h>

int main()
{
    double sum;
    double x;
    printf("Enter the value of x: ");
    scanf("%lf",&x);
    sum=1+x+pow(x,2)/2+pow(x,3)/6+pow(x,4)/24+pow(x,5)/120+pow(x,6)/720;
    printf("The value of e^%f is %.3lf",x,sum);
    return 0;
}

It should be linked with math lib, i.e.:

gcc prog.c -lm
Andriy Berestovskyy
  • 8,059
  • 3
  • 17
  • 33
1

As other people failed to provide proper piece of C code, I have to try it:

#include <stdio.h>
int main() {
    printf("Enter the value of x: ");
    double x;
    scanf("%lf", &x);
    double sum = 1.0 + x * (1.0 + x * (1.0 / 2 + x * (1.0 / 3 + x * (1.0 / 4 + x * (1.0 / 5 + x / 6.0)))));
    printf("The value of e^%.3lf is %.3lf", x, sum);
}
polkovnikov.ph
  • 6,256
  • 6
  • 44
  • 79
0
Better make it dynamic like this one.


#include <stdio.h>

int power(int x,int n){
int sum=1,i;  
if (n == 0)
    return 1;

  for(i=1; i<= n; i++){
    sum *= x;
  }
 return sum;
}

int fact(int n){
 if(n == 0)
   return 1;

 for(i=1; i<= n; i++){
   fact *=i;
 }
  return fact;
}


int main()
{
float sum=0.0;
int i,x,n;
printf("Enter the value of x and n terms: ");
scanf("%d %d",&x,&n);
 for(i=0; i<=n; i++){
  sum += (float)power(x,i)/fact(i);
 }
printf("The value of %d^%d is %.3f",x,n,sum);
return 0;
}
Khurshid
  • 9
  • 2