2011-06-08 19 views
5

Tengo problemas para entender por qué algunas figuras no se pueden representar con el número de coma flotante.Comprender los errores de representación de punto flotante; ¿Qué pasa con mi forma de pensar?

Como sabemos, un flotador normal tendría signo de bit, exponente y mantisa. Por qué no puede, por ejemplo, 0.1 representarse con precisión en este sistema; la forma en que pienso sería poner 10 (1010 en el cubo) en mantisa y -2 en el exponente. Por lo que yo sé, ambos números se pueden representar con precisión en la mantisa y el exponente. Entonces, ¿por qué no podemos representar 0.1 con precisión?

Respuesta

8

Si su exponente es decimal (es decir, representa 10^X), puede representar exactamente 0.1; sin embargo, la mayoría de los formatos de punto flotante utilizan exponentes binarios (es decir, representan 2^X). Dado que no hay enteros X y Y tales que Y * (2^X) = 0.1, no puede representar con precisión 0,1 en la mayoría de los formatos de coma flotante.

Algunos idiomas tienen tipos con ambos exponentes. En C#, por ejemplo, hay un tipo de datos acertadamente llamado decimal que es un formato de coma flotante con un exponente decimal por lo que admitirá almacenar un número como 0.1, aunque tiene otras propiedades poco comunes: El tipo decimal puede distinguir entre 0.1 y 0.10 , y siempre es cierto que x + 1 != x para todos los valores de x.

Para los propósitos más comunes, sin embargo, C# también tiene los tipos de coma flotante float y double que no pueden almacenar con precisión 0.1 porque usan un exponente binario (como se define en IEEE-754). Los tipos de punto flotante binario utilizan menos almacenamiento, son más rápidos porque son más fáciles de implementar y tienen más operaciones definidas en ellos. En general, decimal solo se usa para valores financieros donde la representación exacta de todos los valores decimales es importante y el almacenamiento, la velocidad y el rango de operaciones no lo son.

+1

gracias, el ejemplo de C# es interesante – tsiki

1

Eso sería 10 × 2 -1 = 5, no 0.1.

En general, es como representar un tercio en la base diez: simplemente no es posible con un número finito de dígitos.

Por cierto, 10 = 1,010 ≠ 1100 .

0

Estás pensando en 1 * 10^-1, que funciona para una representación decimal floating number, como decimal en C#. El punto flotante normal (como flotación, doble) utiliza la representación binaria, es decir, en potencias de 2

Normalmente, se utiliza el binario porque se pueden organizar más eficientemente en bits. El decimal se usa normalmente cuando se requiere una precisión decimal absoluta, por ejemplo cuando se cuenta dinero.

2

Cada número en coma flotante en el estándar IEEE 754 es, en efecto, algún entero multiplicado por un poder entero de dos. P.ej., 3 está representado por 3 * 2 , 96 está representado por 3 * 2 , y 3/16 está representado por 3 * 2 -4.

No hay enteros x y y tales que .1 = x * 2 y, por lo tanto .1 no se puede representar exactamente con un número de coma flotante. Prueba: si .1 = x * 2 y, luego 10x = 2 -y. 2 -y es claramente positivo, por lo que x es positivo. También es un número entero, por lo que 10x es divisible por 10, por lo que es divisible por 5. Por lo tanto, 2 -y es una potencia de dos que es divisible por 5, lo cual es claramente imposible.