math.floor java
Extraño comportamiento de coma flotante en un programa Java (4)
El almacenamiento más común para valores de punto flotante en lenguajes de programación - IEEE singles y dobles - no tiene representaciones exactas para la mayoría de las fracciones decimales.
La razón es que almacenan valores en formato binario de coma flotante, en lugar de en formato de coma flotante decimal. Los únicos valores fraccionarios que pueden representarse exactamente son aquellos que son sumas de potencias negativas de dos. Números como:
- 0.5 (2 ^ -1)
- 0.125 (2 ^ -3)
- 0.625 (2 ^ -1 + 2 ^ -3)
Etc.
Lo que está viendo es el hecho de que las representaciones de números como 0.96 no son exactamente representables, porque no se pueden expresar como una suma de potencias negativas de dos. Por lo tanto, cuando se imprimen con total precisión como una fracción decimal, no coincidirán con el valor original.
Esta pregunta ya tiene una respuesta aquí:
- ¿Las matemáticas de punto flotante están rotas? 20 respuestas
En mi programa tengo una matriz con 25 valores dobles 0.04 Cuando trato de sumar estos valores en un ciclo obtengo los siguientes resultados:
0.0 + 0.04 = 0.04
0.04 + 0.04 = 0.08
0.08 + 0.04 = 0.12
0.12 + 0.04 = 0.16
0.16 + 0.04 = 0.2
0.2 + 0.04 = 0.24000000000000002
0.24000000000000002 + 0.04 = 0.28
0.28 + 0.04 = 0.32
0.32 + 0.04 = 0.36
0.36 + 0.04 = 0.39999999999999997
0.39999999999999997 + 0.04 = 0.43999999999999995
0.43999999999999995 + 0.04 = 0.4799999999999999
0.4799999999999999 + 0.04 = 0.5199999999999999
0.5199999999999999 + 0.04 = 0.5599999999999999
0.5599999999999999 + 0.04 = 0.6
0.6 + 0.04 = 0.64
0.64 + 0.04 = 0.68
0.68 + 0.04 = 0.7200000000000001
0.7200000000000001 + 0.04 = 0.7600000000000001
0.7600000000000001 + 0.04 = 0.8000000000000002
0.8000000000000002 + 0.04 = 0.8400000000000002
0.8400000000000002 + 0.04 = 0.8800000000000002
0.8800000000000002 + 0.04 = 0.9200000000000003
0.9200000000000003 + 0.04 = 0.9600000000000003
¿Por qué demonios podría suceder eso?
Es posible que desee comprobar la clase BigDecimal java como una alternativa a los flotadores y dobles.
Otras respuestas mencionaron por qué, pero no cómo evitarlo.
Hay varias soluciones:
- Escala: si todos sus números son múltiplos de 0.01 (por ejemplo), multiplique todo por 100 y use la aritmética de enteros (que es exacta).
- Tipo numérico: si su idioma tiene un tipo numérico (como un tipo
numeric
en SQL), puede usarlo. - Racionales de precisión arbitrarios: use una biblioteca bignum como GMP , que le permite representar estos números como la razón de dos enteros.
- Punto flotante decimal: si tiene un punto flotante decimal como el de IEEE-754r , puede usarlo.
Ver también " Lo que todo informático debe saber sobre el punto flotante "