¿Por qué existe el riesgo de pérdida de precisión durante las operaciones de punto flotante? ¿Cómo resolver el problema de la pérdida de precisión en la aritmética de punto flotante?

¿Por qué existe el riesgo de pérdida de precisión durante las operaciones de punto flotante?

Demostración de código para la pérdida de precisión en la aritmética de coma flotante:

float a = 2.0f - 1.9f;
float b = 1.8f - 1.7f;
System.out.println(a);// 0.100000024
System.out.println(b);// 0.099999905
System.out.println(a == b);// false

¿Por qué surge este problema?

Esto tiene mucho que ver con el mecanismo por el cual las computadoras almacenan números de coma flotante. Sabemos que la computadora es binaria, y cuando la computadora representa un número, el ancho es limitado, cuando el ciclo infinito de decimales se almacena en la computadora, solo se puede truncar, por lo que se perderá la precisión del decimal. Esto también explica por qué los números de punto flotante no se pueden representar con precisión en binario.

Por ejemplo, 0,2 en decimal no se puede convertir con precisión en un decimal binario:

// 0.2 转换为二进制数的过程为,不断乘以 2,直到不存在小数为止,
// 在这个计算过程中,得到的整数部分从上到下排列就是二进制的结果。
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.2 * 2 = 0.4 -> 0(发生循环)
...

Para obtener más información acerca de los números de punto flotante, le sugiero que lea el artículo Conceptos básicos del sistema informático (4) Números de punto flotante .

¿Cómo resolver el problema de la pérdida de precisión en la aritmética de punto flotante?

BigDecimalLas operaciones con números de punto flotante se pueden realizar sin pérdida de precisión. Por lo general, la mayoría de los escenarios comerciales (como los escenarios que involucran dinero) que requieren resultados de cálculo precisos de números de coma flotante se BigDecimalrealizan a través de .

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");

BigDecimal x = a.subtract(b);
BigDecimal y = b.subtract(c);

System.out.println(x); /* 0.1 */
System.out.println(y); /* 0.1 */
System.out.println(Objects.equals(x, y)); /* true */

Para obtener BigDecimaluna introducción detallada a , puede leer este artículo que escribí: Explicación detallada de BigDecimal .

Supongo que te gusta

Origin blog.csdn.net/qq_34337272/article/details/130035600
Recomendado
Clasificación