La compactación de muchos números reales infinitos en un número finito de bits requiere una representación aproximada. La mayoría de los programas almacenan el resultado de cálculos enteros de 32 o 64 bits como máximo. Dado cualquier número fijo de bits, la mayoría de los cálculos con números reales producirán cantidades que no se pueden representar exactamente usando tantos bits. Por lo tanto, el resultado de un cálculo de coma flotante a menudo debe redondearse para que encaje de nuevo en su representación finita. Este error de redondeo es un rasgo característico del cálculo de coma flotante.
Por lo tanto, mientras manejamos cálculos en números de coma flotante (especialmente si los cálculos son en términos de dinero), debemos cuidarnos de los errores de redondeo en un lenguaje de programación.
Veamos un ejemplo:
public class Main { public static void main(String[] args) { double a = 0.7; double b = 0.9; double x = a + 0.1; double y = b - 0.1; System.out.println("x = " + x); System.out.println("y = " + y ); System.out.println(x == y); } }
Producción:
x = 0.7999999999999999 y = 0.8 false
Aquí, la respuesta no es lo que esperábamos, ya que el redondeo lo hizo el compilador de Java.
Motivo del error de redondeo
Los tipos de datos float y double implementan la especificación IEEE de punto flotante 754. Esto significa que los números se representan en una forma como:
SIGN FRACTION * 2 ^ EXP
0.15625 = (0.00101) 2 , que en formato de coma flotante se representa como: 1.01 * 2^-3
No todas las fracciones se pueden representar exactamente como una fracción de una potencia de dos. Como ejemplo simple, 0.1 = (0.000110011001100110011001100110011001100110011001100110011001… ) 2 y, por lo tanto, no se puede almacenar dentro de una variable de coma flotante.
Otro ejemplo:
public class Main { public static void main(String[] args) { double a = 0.7; double b = 0.9; double x = a + 0.1; double y = b - 0.1; System.out.println("x = " + x); System.out.println("y = " + y ); System.out.println(x == y); } }
Producción:
x = 0.7999999999999999 y = 0.8 false
Otro ejemplo:
public class Main { public static void main(String args[]) { double a = 1.0; double b = 0.10; double x = 9 * b; a = a - (x); // Value of a is expected as 0.1 System.out.println("a = " + a); } }
Producción:
a = 0.09999999999999998
¿Cómo rectificar los errores de redondeo?
- Redondear el resultado: la función Round() se puede utilizar para minimizar los efectos de la inexactitud del almacenamiento aritmético de punto flotante. El usuario puede redondear números al número de lugares decimales que requiere el cálculo. Por ejemplo, mientras trabaja con moneda, probablemente redondeará a 2 decimales.
- Algoritmos y funciones: use algoritmos numéricamente estables o diseñe sus propias funciones para manejar tales casos. Puede truncar/redondear dígitos de los que no está seguro de que sean correctos (también puede calcular la precisión numérica de las operaciones)
- Clase BigDecimal: puede usar la clase java.math.BigDecimal , que está diseñada para brindarnos precisión, especialmente en el caso de grandes números fraccionarios.
El siguiente programa muestra cómo se puede eliminar el error:
public
class
Main {
public
static
void
main(String args[])
{
double
a =
1.0
;
double
b =
0.10
;
double
x =
9
* b;
a = a - (x);
/* We use Math.round() function to round the answer to
closest long, then we multiply and divide by 1.0 to
to set the decimal places to 1 place (this can be done
according to the requirements.*/
System.out.println(
"a = "
+ Math.round(a*
1.0
)/
1.0
);
}
}
Producción:
0.1
Ahora obtenemos el resultado esperado, sin el error.
Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por tech manager y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA