Anuncio

Colapsar
No hay ningún anuncio todavía.

Error de precisión en los cálculos

Colapsar
X
 
  • Filtro
  • Hora
  • Mostrar
Borrar todo
nuevos mensajes

  • C/C++ Error de precisión en los cálculos

    Hola, hace tiempo que me venía rondando por la cabeza la idea de la precisión de la representación binaria de los números en coma flotante. He hecho unas pequeñas funciones en C que lo calculan y quería compartirlo con vosotros y escuchar vuestras sugerencias o incluso correcciones. En realidad fue bastante fácil tras leer detenidamente cómo se hace la representación en Wikipedia. Les dejo el código:

    Para obtener el error de redondeo de variables de doble precisión (double):

    Código:
    double error(double x)
    {
    
        if(x==0.0 || log2(fabs(x))<-1022.0)
        {
            return ldexp(1.0,-1074);
        }
        else
        {
            return ldexp(fabs(x),-52);
        }
    
        return NAN;
    
    }
    Y de precisión simple (float):

    Código:
    float errorf(float x)
    {
    
        if(x==0.0f || log2f(fabsf(x))<-126.0f)
        {
            return ldexpf(1.0f,-149);
        }
        else
        {
            return ldexpf(fabsf(x),-23);
        }
    
        return NAN;
    
    }
    Un pequeño ejemplo de prueba:

    Código:
    int main(int nargs, char **argv)
    {
    
        int i;
    
        printf("DOUBLE:\n");
    
        double a,e;
        for(i=0; i<55; i++)
        {
            a = ldexp(1.0,-1021-i);
            e = error(a);
            printf("2^%d => %g +- %g (%g)\n",-1021-i,a,e,e/fabs(a));
        }
    
        printf("\nFLOAT:\n");
    
        float f,ef;
        for(i=0; i<26; i++)
        {
            f = ldexpf(1.0,-125-i);
            ef = errorf(f);
            printf("2^%d => %g +- %g (%g)\n",-125-i,f,ef,ef/fabsf(f));
        }
    
        return 1;
    
    }
    Obviamente las funciones necesitan la librería math.h y compilarse con -lm (GCC) y el ejemplo usa stdio.h.

    Espero que les sea útil.
    Última edición por teclado; 13/11/2016, 09:31:39.

  • #2
    Re: Error de precisión en los cálculos

    Hola teclado, gracias por compartir un programa.
    Tengo algo oxidado C y seguro que tú lo manejas mejor, pero tengo entendido que una igualdad dentro de un if del tipo no es muy efectiva ya que si tu llegas a mediante una operación entre flotantes que de 0 (flotante), nunca es exactamente 0 y la máquina no lo detecta como tal por lo que no te entra en el if. Normalmente lo que se hace en lugar de decir if(x==0.0f) es decir que x esté en el intervalo centrado en el cero y de radio el "épsilon de la máquina", que es el error implícito que aparece al calcular ese cero. Corrígeme si me equivoco
    Saludos,
    [TEX=null]k_BN_A \cdot \dst \sum_{k=0}^{\infty} \dfrac{1}{k!} \cdot 50 \cdot 10_{\text{hex}} \cdot \dfrac{2\pi}{\omega} \cdot \sqrt{-1} \cdot \dfrac{\dd x} {\dd t } \cdot \boxed{^{16}_8\text{X}}[/TEX]

    Comentario


    • #3
      Re: Error de precisión en los cálculos

      Gracias a tí por la respuesta. Sé a lo que te refieres. Sin embargo el if (x==0.0) no es para distinguir casos de uso si no para evitar errores de cálculo (el logaritmo de 0 en particular) fíjate en que la segunda condición es log(abs(x))<-126, eso incluye cierto entorno del 0.0 (el intervalo abierto (-2^-126,2^-126)). Sin embargo creo que tienes razón, la condición completa se puede sustituir tranquilamente por abs(x)<ldexp(1.0,-126).

      Comentario

      Contenido relacionado

      Colapsar

      Trabajando...
      X