Por qué los números de punto flotante pierden precisión
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);
}
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. Es necesario incluir float.h en 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.