El problema de que te muestre nan como resultado es porque estás calculando números demasiado grandes. Realizar una serie de Taylor para el sen(x) con una precisión de 360 (como estás calculando tú) es una locura.
Llamando precisión al número de elementos de la serie que se calculan, tenemos lo siguiente:
Elemento 1: denominador = 1! = (1 * 2 - 1)!
Elemento 2: denominador = 3! = (2 * 2 - 1)!
Elemento 3: denominador = 5! = (3 * 2 - 1)!
Elemento 4: denominador = 7! = (4 * 2 - 1)!
...
Elemento 360: denominador = (360 * 2 - 1)! = 719!
Puedes intentar calcular 719! a ver qué pasa...
Una precisión de 10 es más que suficiente para una aproximación decente.
Dicho esto volvamos con el código en sí. La cosa es calcular cada uno de los elementos de la serie correctamente. Empezamos.
La estructura general del programa es la siguiente:
#include <iostream>
#include <cmath>
using namespace std;
const int PRECISION = 10;
int main() {
double x = 2; // Un valor cualquiera para calcular sen(x)
double resultado = 0;
for(int i = 0; i < PRECISION; ++i) {
resultado += signo * numerador / denominador;
}
cout << "El resultado aproximado de sen(" << x << ") es: " << resultado << endl;
cout << "El resultado real de sen(" << x << ") es: " << sin(x) << endl;
}
Ahora falta calcular cada una de las variables (signo, numerador, denominador).
Para calcular el signo, como ya te dije, basta con ir multiplicando por -1 en cada iteración.
//...
int signo = 1; // Empezamos con 1 porque el primer elemento es positivo
for(int i = 0; i < PRECISION; ++i) {
resultado += signo * numerador / denominador;
signo *= -1; // Cambiamos el signo a -1 para la siguiente iteracion
}
//...
Ahora para calcular el numerador, como ya dije también, hay que darse cuenta de que en cada iteración está elevado a un exponente 2 veces mayor.
Elemento 1: numerador = x^1 = x ^ (1 * 2 - 1)
Elemento 2: numerador = x^3 = x ^ (2 * 2 - 1)
Elemento 3: numerador = x^5 = x ^ (3 * 2 - 1)
...
La primera opción es calcular:
for(int i = 0; i < PRECISION; ++i) {
numerador = pow(x, i * 2 - 1);
//...
}
Pero esto requiere demasiados cálculos innecesarios. Como ya dije:
Lo mismo pasa con una potencia: si tienes x y lo multiplicas por x, ya tienes x^2. Si x^2 lo multiplicas por x, ya tienes x^3 y así sucesivamente también.
Entonces la mejor opción es:
//...
double numerador = x; // El primer numerador es x^1 entonces lo dejamos ya almacenado
for(int i = 0; i < PRECISION; ++i) {
resultado += signo * numerador / denominador;
signo *= -1; // Cambiamos el signo a -1 para la siguiente iteracion
numerador *= (x * x); // Si tenemos x^1 y lo multiplicamos por x^2 (x*x), obtenemos x^3
}
//...
Y ya sólo quedaría el denominador. Vuelvo a mencionar lo que dije en el mensaje anterior:
Piensa que si en una iteración tienes 1! y lo multiplicas por 2, ya tienes 2!. Si 2! lo multiplicas por 3, ya tienes 3!; y así sucesivamente sin tener que hacer todas las operaciones en cada iteración.
Aquí también podríamos calcular el factorial de (2^n-1) pero volverían a ser un montón de cálculos innecesarios. Vamos a ver cómo funcionan los factoriales otra vez:
Elemento 1: denominador = 1! = (1 * 2 - 1)!
Elemento 2: denominador = 3! = (2 * 2 - 1)! = 1! * 2 * 3
Elemento 3: denominador = 5! = (3 * 2 - 1)! = 3! * 4 * 5
Elemento 4: denominador = 7! = (4 * 2 - 1)! = 5! * 6 * 7
...
Como ves, si en la primera iteración tenemos 1!, luego hay que multiplicar por 2 y por 3 para conseguir 3!. Para conseguir el 5! como ya tenemos 3! sólo hay que multiplicar por 4 y por 5 y así sucesivamente.
//...
double denominador = 1; // El primer denominador es 1! (1) entonces lo dejamos ya almacenado
for(int i = 0; i < PRECISION; ++i) {
resultado += signo * numerador / denominador;
signo *= -1; // Cambiamos el signo a -1 para la siguiente iteracion
numerador *= (x * x); // Si tenemos x^1 y lo multiplicamos por x^2 (x*x), obtenemos x^3
denominador *= ((i+2) * 2 - 2) * ((i+2) * 2 - 1);
}
//...
Tenemos que sumar 2 a i porque al empezar en 0, obtendríamos números negativos en las primeras iteraciones. Este valor que se suma a i dependerá del número (i) con el que se empiecen a contar las iteraciones.