Duda calcular radio círculo

Iniciado por welchu, 10 Febrero 2014, 11:27 AM

0 Miembros y 1 Visitante están viendo este tema.

welchu

Ya lo he hecho:

/*Programa que el usuario da el area del circulo y calculamos el radio*/
#include <stdio.h>
float potencia(float base, float exponente)
{
    float resultado=1;
    float i;
   
    for(i=1; i<=exponente; i++)
       resultado *=base;
    return resultado;
}
int main()
{
    float area, radio, pi=3.1415, x, exp=0.5;
   
    printf("Introduce el area del circulo: ");
    scanf("%f", &area);
   
    x=area/pi;
    //r=(x)^(1/2)
   
    printf("El radio del circulo es %f", potencia(x,exp));
   
    getchar();
    getchar();
    return 0;
}



El programa no me da error en ningún sitio pero no me calcula bien el radio. Hay algo que tengo mal?
Gracias

eferion

#11
...

La potencia y la raiz cuadrada no se calculan igual.

La potencia es un simple producto... la raiz cuadrada requiere cálculos adicionales.

Dicho de otra forma... si a la función le pasas un exp = 0.5... y el bucle se repite desde 1 hasta exp... el bucle no se ejecuta NUNCA.

Quieres calcular una raíz cuadrada?? bueno, en mi primera respuesta tienes los pasos a seguir aplicando un algoritmo bastante simple.

NikNitro!

Podrías usar esto:

float raiz(float m)
{
   float i=0;
   float x1,x2;
   while( (i*i) <= m )
           i+=0.1;
   x1=i;
   for(int j=0;j<10;j++)
   {
       x2=m;
       x2/=x1;
       x2+=x1;
       x2/=2;
       x1=x2;
   }

   return x2;
}


Saludos ;)

welchu

Me ha salidooo!!!!!!!

/*Programa que el usuario da el area del circulo y calculamos el radio*/
#include <stdio.h>
float raiz(float m)
{
   float i=0;
   float x1,x2;
   while( (i*i) <= m )
           i+=0.1;
   x1=i;
   for(int j=0;j<10;j++)
   {
       x2=m;
       x2/=x1;
       x2+=x1;
       x2/=2;
       x1=x2;
   }

   return x2;
}

int main()
{
   float area, radio, pi=3.1415, x;
   
   printf("Introduce el area del circulo: ");
   scanf("%f", &area);
   
   x=area/pi;
   //r=(x)^(1/2)
   
   printf("El radio del circulo es %f", raiz(x));
   
   getchar();
   getchar();
   return 0;
}


No es el radio exacto por los decimales del pi pero al fin está bien!
Muchas gracias por vuestra ayuda!!  :D

Gh057

bien welchu, me alegro! el tema es que incrementabas de a uno (i++) cuando lo correcto es usar un incremento float, como bien te indicó NikNitro!, y la función al encapsularla es reutilizable. podrías intentar más adelante implementarla pasándole como parámetro el exponente, para hacerla más general. :) saludos!
4 d0nd3 1r4 3l gh057? l4 r3d 3s 74n v4s74 3 1nf1n1t4...

eferion

Cita de: welchu en 10 Febrero 2014, 14:53 PM
Me ha salidooo!!!!!!!

No es el radio exacto por los decimales del pi pero al fin está bien!
Muchas gracias por vuestra ayuda!!  :D

Ahora la pregunta del millón... sabes cómo o porqué funciona el código que has, literalmente, copiado??

Si la respuesta es negativa, deberías replantearte la forma de resolver los ejercicios... en la vida real no te va a servir esta forma de trabajar.

Gh057

Ahora que tu código anda welchu, si solamente quieres calcular raíces cuadradas podrías usar un algoritmo muy antiguo como el babilónico, (la solución es geométrica, mediante el cálculo de área de un cuadrado) no es tan eficiente como otros más modernos, pero es mucho más limpio y utilizarás menos variables... Te recomiendo buscarlo, leerlo e implementarlo en este ejercicio.

Otra de las soluciones que puedes ver por ahí es el de las series de Taylor, que resuelve el problema mediante logaritmos; la complejidad radica en que la función se encuentra en math.h jejej... pero siempre puedes crear otra función para calcularla mediante matrices (para volcar ahí la tabla). Saludos.
4 d0nd3 1r4 3l gh057? l4 r3d 3s 74n v4s74 3 1nf1n1t4...

Yoel Alejandro

Está muy bien este trabajo, y como comentario quisiera señalar que ese algoritmo:

Código (cpp) [Seleccionar]

float raiz(float m)
{
    float i=0;
    float x1,x2;
    while( (i*i) <= m )
            i+=0.1;
    x1=i;
    for(int j=0;j<10;j++)
    {
        x2=m;
        x2/=x1;
        x2+=x1;
        x2/=2;
        x1=x2;
    }

    return x2;
}


está basado creo que en el "método de Newton" para solución de ecuaciones no lineales, que en el caso de raíces cuadradas también se conoce como método Babilónico.

:)
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

Gh057

Hola yoel_alejandro, efectivamente aunque algo confuso pareciera basarse en el método de Newton (en realidad Newton - Raphson, tuve que buscarlo obviamente!) tengo entendido que fue mientras trabajaba en su famoso método de las fluxiones, que luego se le conoció como derivadas; aunque en ese momento no encontró la relación entre las raíces de polinomios y las sucesiones.

En cambio el método babilónico se basa en una solución geométrica, en llevar los lados de un rectańgulo hasta formar un cuadrado, en donde su lado es la raíz del área del mismo. Es una explicación bastante sosa, es cierto, pero igualmente me tomé el atrevimiento de modificar un poco el código para que sea más entendible, y personamente más intuitivo:


//Programa que el usuario da el area del circulo y calculamos el radio

#include <stdio.h>

double raiz (double);   // prototipo de función raiz.

int main()
{
    double area, pi=3.141519, x;

    printf("Introduce el area del circulo: ");
    fflush( stdin );    // borra el buffer del teclado.
    scanf("%lf", &area);

    x=area/pi;          // y como r=(x)^(1/2)...

    printf("El radio del circulo es %lf\n", raiz(x));

    return 0;
}

double raiz(double x){  // algoritmo de calculo de raíz cuadrada, método babilónico.
   
    double radio = x, t = 0;
   
    while (t != radio){
        t = radio;
        radio = (x/radio + radio)/2;
    }
    return radio;
}


Espero que les sea de su agrado, es tan sólo otra perspectiva... saludos!
4 d0nd3 1r4 3l gh057? l4 r3d 3s 74n v4s74 3 1nf1n1t4...

leosansan

#19
¡¡¡Me ausento unos días y ya están tratado de reinventar la rueda!!!

:rolleyes: :rolleyes: :rolleyes: :rolleyes: :rolleyes:

Vayamos por partes:

Cita de: yoel_alejandro en 10 Febrero 2014, 21:00 PM
Está muy bien este trabajo, y como comentario quisiera señalar que ese algoritmo:
..............................................................
está basado creo que en el "método de Newton" para solución de ecuaciones no lineales, que en el caso de raíces cuadradas también se conoce como método Babilónico.


Como referencia histórica te lo acepto, peros sólo como eso. ;)

Cita de: Gh057 en 11 Febrero 2014, 01:34 AM
...................................................

En cambio el método babilónico se basa en una solución geométrica, en llevar los lados de un rectańgulo hasta formar un cuadrado, en donde su lado es la raíz del área del mismo. Es una explicación bastante sosa, es cierto, pero igualmente me tomé el atrevimiento de modificar un poco el código para que sea más entendible, y personamente más intuitivo:
............................................
Código (cpp) [Seleccionar]
double raiz(double x){  // algoritmo de calculo de raíz cuadrada, método babilónico.
   
   double radio = x, t = 0;
   
   while (t != radio){
       t = radio;
       radio = (x/radio + radio)/2;
   }
   return radio;
}


Creo que te has apuntado un tanto que no es tuyo. Cito textualmente el método expuesto en la Wikipedia:

Código (cpp) [Seleccionar]
double raiz(double x){
   double r = x, t = 0;
   while (t != r){
       t = r;
       r = (x/r + r)/2;
   }
   return r;
}


Reconoce que el parecido es cuanto menos asombroso. ;)

Lo de eferion no termino de entender lo último:

Cita de: eferion en 10 Febrero 2014, 11:41 AM
Podrías optar por un algoritmo que vaya calculando la raiz cuadrada por aproximación y mediante un mecanismo de prueba y error.

1. Empiezas por un número... por ejemplo el 1
2. Ahora asignas un incremento... por ejemplo una unidad.
................................................
También puedes optar por algoritmos más sofisticados y potentes... pero esos no se si los vas a entender y no creo que sean el objetivo de tu práctica.

Como vaya a calcular la raíz de 10000000 va a tener que iterar 10000000 de veces antes de empezar las aproximaciones propiamente dichas. Y lo del incremento arbitrario que tomas lo admito, como lo anterior, como ejemplo. pero sólo como eso. En cualquier caso alabo tu "ocurrencia" para no hablar de métodos que consideras más sofisticados. ;)

Por cierto, ¿de qué algoritmos sofisticados hablas?. Porque yo puedo mencionar algunos elementales como los métodos de la bisección o bipartición,  Regula Falsi, Secante,  Iteración del punto fijo, Newton y sus tropecientas variantes, por mencionar sólo los elementales y todos ellos aplicables por cualquiera que haya estudiado simplemente el Bachillerato.

En el fondo la sensación que me da es que el hecho de tener que calcular la raíz cuadrada ha ofuscado al personal, cuando en este caso se se trata simplemente de obtener la raíz de una función:

Código (cpp) [Seleccionar]
f(x)=x*x-N=0

Personalmente me habría decantado por el Método de bisección por lo simple y fácil de explicar y/o entender, insisto que con un mínimo conocimiento de las Mates del Bachillerato. Y como ejemplo de la impementación al cáculo de la raíz cuadrada de 7:

Código (cpp) [Seleccionar]
#include <stdio.h>
#include<stdlib.h>
#include <math.h>
#define f(x)    (x*x-7)

int main( void )
{
   double a=2,b=3,c=0,h=.000000001,FA=0,FB=0,FC=0;
   int i=1;

  /* if (f(b)*f(a)<0.){
     printf("Como signo de f(b)*f(a) es negativo, hay solucion\n");
   else {
     printf("Como signo de f(b)*f(a) es positivo, hay que elegir otro intervalo.");
.......................................
   }*/

   c=(a+b)/2;
   while ((b-a)>=h ){
       FA=f(a),FB=f(b),FC=f(c);
       if ((FA* FC )>0 ){
         a=c;
         FA=FC;
       }
       else {
         b=c;
         FB=FC;
       }
       c = (a+b)/2;
       i++;
   }
    printf("\n\nLa raiz de %1.8g es %1.8lf.\n\nY el valor real es %1.8lf: \n\nsiendo el numero de iteraciones %d\n\n",N,c,sqrt(N),i);
   return 0;
}


Citar

La raiz de 7 es 2.64575131.

Y el valor real es 2.64575131:

siendo el numero de iteraciones 31

Lo que sí es importante poner de manifiesto es la trascendencia de elegir adecuadamente los valores del intervalo en que se encuentra la raíz a fin de una pronta aproximación a la solución de la ecuación, toda vez que al tratarse de un simple polinomio de grado dos cumple los requisitos exigidos por el método, este y los otros mencionados anteriormente. Pero al tratarse en este caso de hallar la raíz cuadrada de un número real es la obtención de dicho intervalo es algo obvio.


Espero que nadie se sienta ofendido y/o molesto por mis comentarios. Sólo pretendo aportar otro punto de vista al derrotero en que había caído el tema. ;)


¡¡¡¡ Saluditos! ..... !!!!