Autor Tema: Tabular función en lenguaje C

0 Usuarios y 2 Visitantes están viendo este tema.

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

leonardo09

  • Leonardo Andrés Jofré Flor
  • Experto
  • Mensajes: 798
  • 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: 46,431
  • País: es
  • Karma: +0/-0
  • Sexo: Masculino
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
  • Experto
  • Mensajes: 798
  • 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: 46,431
  • País: es
  • Karma: +0/-0
  • Sexo: Masculino
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
  • Experto
  • Mensajes: 798
  • 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
  • Experto
  • Mensajes: 798
  • 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: 46,431
  • País: es
  • Karma: +0/-0
  • Sexo: Masculino
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
  • Experto
  • Mensajes: 798
  • 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
  • Experto
  • Mensajes: 798
  • 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: 46,431
  • País: es
  • Karma: +0/-0
  • Sexo: Masculino
Hola

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

Saludos.

01 Julio, 2008, 07:39 pm
Respuesta #10

leonardo09

  • Leonardo Andrés Jofré Flor
  • Experto
  • Mensajes: 798
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
Observa , el manco , con este mismo programa , una pregunta :¿Que compilador tienes?
nunca seré buen matemático

01 Julio, 2008, 07:46 pm
Respuesta #11

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 46,431
  • País: es
  • Karma: +0/-0
  • Sexo: Masculino
Hola

 Mi compilador es el:

Bloodshed Dev C++

 Pero fíjate que la tabla de valores no corresponde, más alla del ERROR, en ningún punto a tu función. Revisa bien tu programa. Yo simplemente hice un copy pega de lo que pusiste en tu mensaje y me funciona perfectamente.

 Revisa bien!!!!

Saludos.

01 Julio, 2008, 07:52 pm
Respuesta #12

leonardo09

  • Leonardo Andrés Jofré Flor
  • Experto
  • Mensajes: 798
  • Karma: +0/-0
  • Sexo: Masculino
  • Leonardo Jofré
    • Leonardo Andrés Jofré Flor
yo tambien hice un copi y pega....
este lenguaje es muy caprichoso¡¡¡¡
nunca seré buen matemático

01 Julio, 2008, 07:57 pm
Respuesta #13

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 46,431
  • País: es
  • Karma: +0/-0
  • Sexo: Masculino
Hola

 Tiene que haber algo, los números de tu tabla no tienen sentido.

 Prueba a modificar la función y. Por ejemplo poniendo un valor constante o luego algo lineal. Cosas muy simples, triviales. Así se detectan los errores.

Saludos.

15 Julio, 2008, 08:21 am
Respuesta #14

Daniel

  • Novato
  • Mensajes: 151
  • Karma: +0/-0
  • Sexo: Masculino
    • Worksheets Site
creo que este es un problema de multiplicación de flotante por constante entera. Muerte a los lenguajes tipeados estáticamente:

http://en.wikipedia.org/wiki/Programming_language#Typed_versus_untyped_languages