Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Beginner Web en 28 Marzo 2019, 04:11 am



Título: funcion coseno
Publicado por: Beginner Web en 28 Marzo 2019, 04:11 am
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 :(

Código
  1. main()
  2. {
  3. int i, terminos=8;
  4. double x=1, coseno=0;
  5. for(i=1;i<=terminos;i++)
  6. coseno+=pow(-1,i)*(pow(x,2*i)/factorial(i));
  7. cout<<"Coseno("<<x<<"): "<<coseno<<endl;
  8. }

Código
  1. int factorial(int n)
  2. {
  3. if(n==0)
  4. return 1;
  5. else
  6. return n*factorial(n-1);
  7. }

No se ve la funcion pero hagan de cuenta que lo del main es la funcion double coseno(terminos, x){...}


Título: Re: funcion coseno
Publicado por: K-YreX en 28 Marzo 2019, 13:39 pm
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:
Código:
P(x) = 1 - x²/2! + x⁴/4! - x⁶/6! + x⁸/8!... 
Y en tu caso estás calculando:
Código:
P(x) = - x²/2! + x⁴/3! - x⁶/4!... 


Título: Re: funcion coseno
Publicado por: Beginner Web en 29 Marzo 2019, 00:57 am
Y como es la formula?


Título: Re: funcion coseno
Publicado por: K-YreX en 29 Marzo 2019, 01:20 am
En C++ el bucle para calcular la fórmula sería algo así:
Código
  1. double cos = 0;
  2. int exponente = 0;
  3. for(size_t i = 0; i < num_terminos * num_terminos; i += 2, exponente++)
  4.    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:
Código
  1. int factorial(int n){
  2.    if(n < 1)
  3.        return 1;
  4.    else
  5.        return n * factorial(n-1);
  6. }


Título: Re: funcion coseno
Publicado por: Beginner Web en 29 Marzo 2019, 01:43 am
No me sale, en num_terminos que va?

tengo esto no se que estoy haciendo mal

Código
  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. using namespace std;
  6.  
  7. int factorial(int n)
  8. {
  9. if(n<1)
  10. return 1;
  11. else
  12. return n*factorial(n-1);
  13. }
  14.  
  15. long double coseno(int numero)
  16. {
  17. long double cos=0;
  18. int terminos=5, exponente=0;
  19. for(size_t i = 0; i < terminos * terminos; i += 2, exponente++)
  20.     cos += pow(-1,exponente) * pow(numero,i)/factorial(i);
  21.    return cos;
  22. }
  23.  
  24. main()
  25. {
  26. cout<<"Coseno: "<<coseno(10)<<endl;
  27. }


Título: Re: funcion coseno
Publicado por: K-YreX en 29 Marzo 2019, 02:29 am
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.
Código
  1. // aproximacion del numero PI
  2. const double PI = 3.141592;
  3.  
  4. long double coseno(double numero)
  5. {
  6.        // reduce el angulo a la primera vuelta de forma simple
  7. while(numero > 2*PI)
  8. numero -= 2*PI;
  9. long double cos=0;
  10. int terminos=10, exponente=0;
  11. for(size_t i = 0; i < terminos; i += 2, exponente++)
  12.     cos += pow(-1,exponente) * pow(numero,i)/factorial(i);
  13.    return cos;
  14. }


Título: Re: funcion coseno
Publicado por: Beginner Web en 29 Marzo 2019, 02:42 am
En la calculadora me sale 0,984807753 y en la consola me sale -0,713883  :huh:


Título: Re: funcion coseno
Publicado por: K-YreX en 29 Marzo 2019, 02:54 am
Como comentaba antes, el programa recibe un ángulo en radianes.
En la calculadora lo estás calculando en grados.
Código:
angulo_grad = x
andulo_rad = x * PI / 180


Título: Re: funcion coseno
Publicado por: Beginner Web en 29 Marzo 2019, 03:11 am
Haa en algun lado lo vi, sabia que tenia que ver con eso,bueno muchas gracias por tu ayuda :)  ;-)



Título: Re: funcion coseno
Publicado por: Beginner Web en 20 Abril 2019, 23:01 pm
En C++ el bucle para calcular la fórmula sería algo así:
Código
  1. double cos = 0;
  2. int exponente = 0;
  3. for(size_t i = 0; i < num_terminos * num_terminos; i += 2, exponente++)
  4.    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:
Código
  1. int factorial(int n){
  2.    if(n < 1)
  3.        return 1;
  4.    else
  5.        return n * factorial(n-1);
  6. }

No me convence tu algoritmo factorial porque aun sigue haciendo una llamada recursiva adicional   :laugh:


Título: Re: funcion coseno
Publicado por: Serapis en 21 Abril 2019, 09:46 am
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):

Código:
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).
Código:
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...
Código:
     ...
     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...


Título: Re: funcion coseno
Publicado por: Beginner Web en 22 Abril 2019, 04:18 am
Pero aun sigues haciendo una llamada adicional  :laugh:  ;-)

Código
  1. int factorial(int n)
  2. {
  3. if(n<2)
  4. return 1;
  5. else
  6. return n*factorial(n-1);
  7. }


Título: Re: funcion coseno
Publicado por: CalgaryCorpus en 22 Abril 2019, 15:14 pm
El reemplazo de la recursion por la version iterativa no parece estar calculando el factorial.

n = n + (n * k)

La suma parece estar demas.


Título: Re: funcion coseno
Publicado por: Serapis en 22 Abril 2019, 15:38 pm
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.


Título: Re: funcion coseno
Publicado por: Beginner Web en 22 Abril 2019, 16:17 pm
 :laugh: