Autor Tema: Tabular función en lenguaje C

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

25 Junio, 2008, 12:33 am
Leído 17795 veces

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
estoy tabulando la función \( \displaystyle\frac{2}{2-x} \)
en C con el siguiente codigo:

#include <stdio.h>
#include <conio.h>
main ()
{
     float x,y,z;
     x=-2;
     z=0.1;
     printf("   x|y\n");
     printf ("----+-----\n");
     do
     {
          if (x==2)
         
          printf("%4.1f|?\n",x);
         
          else
          {
         
          y=2/(2-x);
          printf("%4.1f|%5.2f\n",x,y);
          }
          x=x+z;
          }
         
          while (x<=4);
     
     getchar();}

y funciona solamente cuando \( z=0.5k \mbox{ con } k \mbox{entero} \)¿Cuál es la razon que las indeterminaciones solo se vean con esa condición ¿cuál es el error del código?
nunca seré buen matemático

25 Junio, 2008, 11:37 am
Respuesta #1

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 55,837
  • País: es
  • Karma: +0/-0
Hola

 ¿A qué te refieres con que "funcione o no"?. ¿Qué ocurre exactamente si le das otros valores a \( z \)?.

Saludos.

25 Junio, 2008, 10:27 pm
Respuesta #2

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
como ves , \( z \) se va sumando a \( x \) en cada iteración , cuando \( z=0.5,1,1.5 \) , por eso me dice el programa "step" para cada iteración en el tabulado , pero , mira intenta conpilar cuando \( z=0.1 \)
entoncers en el tabulado cuando \( x=2 \) , o sea donde se indetermina la funcion ,  no te da el caracter \( ? \) que significa la indeterminación en el programa.
nunca seré buen matemático

25 Junio, 2008, 10:52 pm
Respuesta #3

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 55,837
  • País: es
  • Karma: +0/-0
Hola

 Ah. Ya entiendo.

 El problema está en que el ordenador sólo puede almacenar una cantidad finita de cifras decimales y eso hace que aparezcan errores de redondeo que se hacen mayores cuantas más operaciones acumulamos.

 Por eso en general para número en coma flotante las "igualdades" funcionan muy mal y es mejor para detectar si un número es igual a otro, cotejar más bien que está suficientemente cerca, es decir, sustituir:

 x==2

 por

 abs(x-2)<=0.0000001
 
 por ejemplo.

 Ten en cuenta además que el ordenador trabaja en sistema binario. Mientras que 0.5 en sistema binario sigue siendo un número con una cantidad finita de decimales; 0.1 al pasarlo a binario nos da un número con infinitas cifras decimales. De ahí que con el primer paso te funcione y con el segundo no, porque \( x \) nunca llega a ser exactamente \( 2 \).

 En general la fracción reducida \( n/m \) puede representarse en binario con un número finito de decimales sólo si \( m \) es una potencia de dos.

Saludos.

25 Junio, 2008, 11:01 pm
Respuesta #4

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
Y como se corrige esto??
como lo hacen las calculadoras para tabular entonces como la \( f_x570ES \) ( ES UNA CALCULADORA )
nunca seré buen matemático

25 Junio, 2008, 11:16 pm
Respuesta #5

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
`abs' undeclared (first use this function)
¿En que librería está?
nunca seré buen matemático

26 Junio, 2008, 08:59 am
Respuesta #6

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 55,837
  • País: es
  • Karma: +0/-0
Hola

Citar
Y como se corrige esto??
como lo hacen las calculadoras para tabular entonces como la \( f_x570ES \)  ( ES UNA CALCULADORA )

Pues la calculadora directamene le daría valores a \( x \) y calcularía \( 2/(2-x) \). Si el denominador es cero o muy pequño al "intentar" hacer la división le dará un número "demasiado grande", con lo cual detecta un error de OVERFLOW, que puede ser gestionado de mil maneras dependiendo de como la hayan programado: ignorarlo no representando ese punto, dando un mensaje de error, dándole el valor simbólico infinito, etcétera...

En realidad tu programa funciona. Simplemente como \( x \) nunca (para ciertos pasos) vale exactamente \( 2 \) pues no pone ese símbolito "?", pero si te calcula la imagen de \( x \). Si \( x \) es muy próximo a \( 2 \) te da un valor muy grande.

La función abs está en stdlib.h

Saludos.

26 Junio, 2008, 09:16 am
Respuesta #7

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
mira (o miren fuera mejor) , esta si que está extraña:
en un programa que tabula \( \displaystyle\frac{2x^2-1}{x^3-6x^2+11x-1} \)
Código: [Seleccionar]
#include <stdio.h>
#include <stdlib.h>

#include <conio.h>

main ()
{
     float y;
     float x,z;
     float a,b,g;
     
     
     printf("punto inicial:");
     scanf("%f",&a);
     printf("punto final:");
     scanf("%f",&b);
     printf("step?:\n");
     scanf("%f",&z);
     x=a;
     printf("   x|y   |g\n");
     printf ("----+-----\n");
     do
     {
            g=(x*x*x-6*x*x+11*x-1);
          if (g==0)
         
          printf("%4.1f|ERROR\n|",x/10);
         
          else
          {
         
          y=(2*x*x-1)/(x*x*x-6*x*x+11*x-1);
          printf("%4.1f|%5.10f\n|",x,y);
          }
         
         x=x+z;
          ;
          }
         
          while (x<=b);
     
     getche();
     }
se ve claramente que la funcion es de la forma \( \displaystyle\frac{f(x)}{g(x)} \) y se ve con rojo que me diera error cuando \( g(x)=0 \) o sea el denominadr fuese \( 0 \) pero me tira el indeterminado cuando \( x=2 \) que no esta ni cerca de ser indeterminado. ¿Por qué será?
nunca seré buen matemático

26 Junio, 2008, 09:19 am
Respuesta #8

leonardo09

  • Leonardo Andrés Jofré Flor
  • $$\Large \color{#c88359}\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 786
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
Voy a poner el codigo aca por que en la versión código queda ilegible

#include <stdio.h>
#include <stdlib.h>

#include <conio.h>

main ()
{
     float y;
     float x,z;
     float a,b,g;
     
     
     printf("punto inicial:");
     scanf("%f",&a);
     printf("punto final:");
     scanf("%f",&b);
     printf("step?:\n");
     scanf("%f",&z);
     x=a;
     printf("   x|y   |g\n");
     printf ("----+-----\n");
     do
     {
            g=(x*x*x-6*x*x+11*x-1);
          if (g==0)
         
          printf("%4.1f|ERROR\n|",x/10);

         
          else
          {
         
          y=(2*x*x-1)/(x*x*x-6*x*x+11*x-1);
          printf("%4.1f|%5.10f\n|",x,y);
          }
         
         x=x+z;
          ;
          }
         
          while (x<=b);
     
     getche();
     }
nunca seré buen matemático

26 Junio, 2008, 11:02 am
Respuesta #9

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 55,837
  • País: es
  • Karma: +0/-0
Hola

 ¿Con qué datos de entrada estás probando? A mi me va perfectamente y no me da indeterminado en \( x=2 \).

Saludos.