Compartir a través de


Por qué los números de punto flotante pierden precisión

Actualización: noviembre 2007

En general, los valores decimales de punto flotante no tienen una representación binaria exacta. Éste es un efecto secundario derivado de la forma en que la CPU representa los datos de punto flotante. Por esta razón, estos datos podrían perder precisión y algunas operaciones de punto flotante podrían producir resultados inesperados.

Este comportamiento es el resultado de una de las causas siguientes:

  • La representación binaria del número decimal puede no ser exacta.

  • Los tipos de los números utilizados no coinciden (por ejemplo, cuando se mezclan los tipos de datos float y double).

Para corregir este comportamiento, la mayoría de los programadores se aseguran de que el valor sea mayor o menor que el necesario, o utilizan una biblioteca en formato Binary Coded Decimal (BCD), que mantendrá la precisión.

La representación binaria de los valores de punto flotante afectan a la precisión y la exactitud de los cálculos de punto flotante. Microsoft Visual C++ utiliza el Formato de punto flotante de IEEE.

Ejemplo

// Floating-point_number_precision.c
// Compile options needed: none. Value of c is printed with a decimal 
// point precision of 10 and 6 (printf rounded value by default) to 
// show the difference
#include <stdio.h>

#define EPSILON 0.0001   // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))

int main() {
   float a, b, c;

   a = 1.345f;
   b = 1.123f;
   c = a + b;
   // if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result
   if (c == 2.468)            // Comment this line for correct result
      printf_s("They are equal.\n");
   else
      printf_s("They are not equal! The value of c is %13.10f "
                "or %f",c,c);
}

They are not equal! The value of c is  2.4679999352 or 2.468000

Comentarios

Para EPSILON, puede utilizar la constante FLT_EPSILON, que se define como 1,192092896e-07F para datos de tipo float, o la constante DBL_EPSILON, que se define como 2,2204460492503131e-016 para datos de tipo double. Deberá incluir float.h para estas constantes. Se definen como el menor número positivo x tal que x+1,0 no sea igual que 1,0. Como se trata de un número muy pequeño, debe utilizar la tolerancia definida por el usuario en los cálculos que impliquen el uso de números muy grandes.

Vea también

Referencia

Optimizar el código