Question
Q16. Write a program to evaluate sine value of pi/2 in degrees entered by the user using the following series. Prompt the user to enter the number of terms to evaluate.sin(x) = x-x3/3! + x5/5! -….
Problem in Code given below
When number of truncation terms are taken 10, it gives correct output. But when n is declared as 100, it gives nan. Why?
#include<iostream>
#include<cmath>
usingnamespace std;
int fact(int n)
{
int fact =1;
int i;
for (i=1;i<=n;i++)
{
fact = fact*i;
}
return fact;
}
int main()
{
int i,n;
float angle, sum = 0;
cout<<"Enter angle in radians";
cin>>angle;
cout<<"Enter number of terms for truncation";
cin>>n;
for(i=0;i<n;i++)
{
sum = sum+ (pow(-1,i)*pow(angle, 2*i+1))/fact(2*i+1);
}
cout<<"sum="<<sum;
return 0;
}
@abcdef123,
It is a common illusion that the factorial being a convenient way of writing the formula means that it makes any sense to calculate it that way. The factorial function grows too fast to make this useful and it's going in the denominator anyway.
It is also highly inefficient to calculate each new term from scratch: each one is a multiple of the previous one with four new factors and a reversal of sign.
you can just make a lookup vector of factorials and grab the values off a website if you need a fact function. Calculation of them up to 64 bit integers is just spinning the CPU for nothing.
past 64 bits, you need a big-int class or assembly that can use the 128 bit register and it gets a little more 'exiting'.
but here, as noted, you don't even need that; its the previous value * something, and you can sign flip via pow(-1, iteration) or better yet int sign[2] = {-1,1} and a modulo on iteration (watch zero and % in loops, or you'll get a double zero bug, be mindful of it).
computers have limits. Factorials and large powers run it dry fast, n=100 may not be possible to do using conventional data types, and even if it DID give the right answer, you have found more significant digits than you can print in a double. I am guessing (you can determine it yourself) that 10-15 is about as much as you need to get all the digits you can use.
not sure what a long double is (32, 64 bit floating point types are the IEEE types you can use on most hardware and that is float, double) but some compilers support the tenbyte double which is what the FPU uses internally. The *intent* of the 10b is to give extra digits to minimize roundoff errors internally in the FPU. But for some simple algorithms with minimal roundoff you can use the 10b double from the FPU safely. There is a 128 bit format but I don't know what machines and compilers support it. You machine may or may not think a long double is 128. I think some OS / setups do something internally (not on the FPU) that can give oddball precision but more than 80 and less than 128. I never used anything like that, so this is a dim memory.