Hola como hago para hacer la formula de Maclaurin pero enviando a esa funcion 1 solo parametro? :huh:
Porque este no me da ademas son dos parametros que le mando, quiero mandar solo el angulo :(
main()
{
int i, terminos=8;
double x=1, coseno=0;
for(i=1;i<=terminos;i++)
coseno+=pow(-1,i)*(pow(x,2*i)/factorial(i));
cout<<"Coseno("<<x<<"): "<<coseno<<endl;
}
int factorial(int n)
{
if(n==0)
return 1;
else
return n*factorial(n-1);
}
No se ve la funcion pero hagan de cuenta que lo del main es la funcion double coseno(terminos, x){...}
Imagino que quieres una función que calcule el <cos(x)> usando el Polinomio de Taylor. La forma de pasar un único argumento es predefinir un número constante para <terminos>. Al fin y al cabo cuanto mayor sea <terminos>, mayor será la precisión/exactitud del resultado. Entonces puedes declarar como constante <terminos = 10> y usar siempre ese número.
Además me parece que el Polinomio de Taylor para la función <coseno> no es esa. La función <cos(x)> se aproxima usando el polinomio:
P(x) = 1 - x²/2! + x⁴/4! - x⁶/6! + x⁸/8!...
Y en tu caso estás calculando:
P(x) = - x²/2! + x⁴/3! - x⁶/4!...
Y como es la formula?
En C++ el bucle para calcular la fórmula sería algo así:
double cos = 0;
int exponente = 0;
for(size_t i = 0; i < num_terminos * num_terminos; i += 2, exponente++)
cos += pow(-1,exponente) * pow(x,i)/factorial(i);
Y si la función factorial la modificas un poco, te ahorras una llamada para calcular cada factorial:
int factorial(int n){
if(n < 1)
return 1;
else
return n * factorial(n-1);
}
No me sale, en num_terminos que va?
tengo esto no se que estoy haciendo mal
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
int factorial(int n)
{
if(n<1)
return 1;
else
return n*factorial(n-1);
}
long double coseno(int numero)
{
long double cos=0;
int terminos=5, exponente=0;
for(size_t i = 0; i < terminos * terminos; i += 2, exponente++)
cos += pow(-1,exponente) * pow(numero,i)/factorial(i);
return cos;
}
main()
{
cout<<"Coseno: "<<coseno(10)<<endl;
}
Hay un problema con el factorial que si intentamos calcular factoriales muy grandes como por ejemplo 24! que llega a calcularse en ese programa que muestras, se produce un desbordamiento. El <num_terminos> muestra la precisión porque determina el número de términos que se van a calcular.
Además hay que tener en cuenta que los ángulos se pasan en radianes. Por lo que 10 radianes es mucho. Para que funcione correctamente hay que reducir el ángulo a la primera vuelta. Reduciendo un poco el número de términos para evitar el desbordamiento del factorial, ya salen resultados bastante bien aproximados.
// aproximacion del numero PI
const double PI = 3.141592;
long double coseno(double numero)
{
// reduce el angulo a la primera vuelta de forma simple
while(numero > 2*PI)
numero -= 2*PI;
long double cos=0;
int terminos=10, exponente=0;
for(size_t i = 0; i < terminos; i += 2, exponente++)
cos += pow(-1,exponente) * pow(numero,i)/factorial(i);
return cos;
}
En la calculadora me sale 0,984807753 y en la consola me sale -0,713883 :huh:
Como comentaba antes, el programa recibe un ángulo en radianes.
En la calculadora lo estás calculando en grados.
angulo_grad = x
andulo_rad = x * PI / 180
Haa en algun lado lo vi, sabia que tenia que ver con eso,bueno muchas gracias por tu ayuda :) ;-)
Cita de: YreX-DwX en 29 Marzo 2019, 01:20 AM
En C++ el bucle para calcular la fórmula sería algo así:
double cos = 0;
int exponente = 0;
for(size_t i = 0; i < num_terminos * num_terminos; i += 2, exponente++)
cos += pow(-1,exponente) * pow(x,i)/factorial(i);
Y si la función factorial la modificas un poco, te ahorras una llamada para calcular cada factorial:
int factorial(int n){
if(n < 1)
return 1;
else
return n * factorial(n-1);
}
No me convence tu algoritmo factorial porque aun sigue haciendo una llamada recursiva adicional :laugh:
Deberías aprender a pasar llamadas recursivas a iterativas y viceversa (el viceversa suele ser la mayoría de las veces más sencillo).
Así sería calcular el factorial en un simple bucle (es decir pasado a iterativo):
j = 10 // factorial entre 1 y 10
n = 1
bucle para k desde 2 a j // si 'j' fuere 0, ó 1 todavía arrojará el valor correcto con n = 1
n = (n * k)
fin bucle
Ahora bien, dado que estás usando el factorial dentro de un bucle, vas a calcular innumerables veces el factorial de un número, incluso muchas veces podría ser el mismo valor, más aún, si luego la función que usa dicho bucle es llamada múltiples veces, resultará que estás ejecutando casi todo el tiempo el factorial de un número en vez de hacer otras cosas...
...en tales situaciones es mejor pre-calcular una úncia vez el factorial para cada número hasta el máximo, y guardarlo en un array, así luego basta tomar el iésimo valor del array.
Si la función se llamara una única vez, bastaría precalcularlo al entrar en la propia función, pero si la función fuere invocada múltiples veces entonces es mejor precalcularla al inicializar el componente de código del que forma parte.
Nótese que con apenas el factorial de 16 ya arroja: 20.922.789.888.000, es decir algo más de 2^44... así que el array tendrá un tamaño relativamente pequeño. es decir consumirá muy poca memoria, tan poca que incluso los lenguajes podrían tenerlo como constantes (para 32 bits, basta llegar hasta el factorial de 12).
array de int factoriales() // en realidad dimensionar el array al número de indices que deba contener como máximo...
funcion PrecalcularFactorial(int x)
int k, n
n = 1
factoriales(0) = n
factoriales(1) = n
bucle para k desde 2 a x
n = (n * k)
factoriales(k) = n
fin bucle
fin funcion
Ahora cuando tengas que usarlo...en vez de ser una llamada a una función o una ejecución en un bucle, será una dirección de memoria que ya contiene el valor...
...
cos += pow(-1,exponente) * pow(x,i)/factoriales(i);
...
...con lo cual el tiempo invertido será únicamente el de acceso al array, que, comparado con la pérdida de tiempo de estar contínuamente recalculando el factorial, el ahorro en tiempo será notorio...
Pero aun sigues haciendo una llamada adicional :laugh: ;-)
int factorial(int n)
{
if(n<2)
return 1;
else
return n*factorial(n-1);
}
El reemplazo de la recursion por la version iterativa no parece estar calculando el factorial.
n = n + (n * k)
La suma parece estar demas.
Cierto, un lapsus mental... Gracias CalgaryCorpus, lo corrijo
Ana, tu comentario precedente ya lo esgrimiste anteriormente a una respuesta previa que te dieron, pero ahora no procede.
:laugh: