Calculation the Taylor series of sinh
The function calculates the value of sinh(x) using the following development in a Taylor series:
I want to calculate the value of sinh(3) = 10.01787, but the function outputs 9. I also get this warning:
1>main.c(24): warning C4244: 'function': conversion from 'double' to 'int', possible loss of data
This is my code:
int fattoriale(int n)
{
int risultato = 1;
if (n == 0)
{
return 1;
}
for (int i = 1; i < n + 1; i++)
{
risultato = risultato * i;
}
return risultato;
}
int esponenziale(int base, int esponente)
{
int risultato = 1;
for (int i = 0; i < esponente; i++)
{
risultato = risultato * base;
}
return risultato;
}
double seno_iperbolico(double x)
{
double risultato = 0, check = -1;
for (int n = 0; check != risultato; n++)
{
check = risultato;
risultato = risultato + (((esponenziale(x, ((2 * n) + 1))) / (fattoriale((2 * n) + 1))));
}
return risultato;
}
int main(void)
{
double numero = 1;
double risultato = seno_iperbolico(numero);
}
Please help me fix this program.
It is actually pretty great that the compiler is warning you about this kind of data loss.
You see, when you call this:
esponenziale(x, ((2 * n) + 1))
You essentially lose your accuracy since you are converting your double , which is x , to an int . This is since the signature of esponenziale is int esponenziale(int base, int esponente) .
Change it to double esponenziale(double base, int esponente) , risultato should be a double as well, since you are returning it from the function and performing mathematical operations with/on it.
Remember that dividing a double with an int gives you a double back.
Edit: According to ringø's comment, and seeing how it actually solved your issue, you should also set double fattoriale(int n) and inside that double risultato = 1; .
You are losing precision since many of the terms will be fractional quantities. Using an int will clobber the decimal portion. Replace your int types with double types as appropriate.
Your factorial function will overflow for surprisingly small values of n . For 16 bit int , the largest value of n is 7, for 32 bit it's 12 and for 64 bit it's 19. The behaviour on overflowing a signed integral type is undefined. You could use unsigned long long or a uint128_t if your compiler supports it. That will buy you a bit more time. But given you're converting to a double anyway, you may as well use a double from the get-go. Note that an IEEE764 floating point double will hit infinity at 171!
Be assured that the radius of convergence of the Maclaurin expansion of sinh is infinite for any value of x . So any value of x will work, although convergence might be slow. See http://math.cmu.edu/~bkell/21122-2011f/sinh-maclaurin.pdf.
下一篇: 计算sinh的泰勒级数
