Recientemente estudié los problemas de cálculo de punto flotante de Java, consulté información relevante de Internet, resumí y realicé algunas clasificaciones y depuraciones, y finalmente completé este artículo. Todos pueden señalar los errores y problemas.
En Java, las variables declaradas por float son números de punto flotante de precisión simple y las variables declaradas por double son números de punto flotante de doble precisión. Como su nombre lo indica, las entidades de tipo doble ocupan el doble del espacio de memoria que float. float tiene 4 bytes y double tiene 8 bytes. Los datos de tipo flotante y doble no pueden representar con precisión los resultados de los cálculos. Esto se debe a que los datos flotantes y dobles son cálculos imprecisos. Puedes ver esto a través del siguiente código:
Copie el código de código de la siguiente manera:
prueba de clase pública
{
principal vacío estático público (String [] argumentos)
{
System.out.println(0,05 + 0,01);
System.out.println(1,0 - 0,42);
System.out.println(4.015 * 100);
System.out.println(123,3/100);
}
}
El resultado de correr es:
0.060000000000000005
0.5800000000000001
401.49999999999994
1.232999999999999999
Para obtener el efecto deseado, podemos intentar usar java.text.DecimalFormat para formatear números de punto flotante:
DecimalFormat puede formatear números de acuerdo con un formato determinado. Los caracteres de formato más utilizados son #, 0, etc. ejemplo:
Copie el código de código de la siguiente manera:
System.out.println(new java.text.DecimalFormat("0.00").format(3.125));
System.out.println(new java.text.DecimalFormat("0.00").format(3.135));
Pero el resultado es:
3.12
3.14
Esto se debe a que DecimalFormat utiliza el redondeo medio par (ROUND_HALF_EVEN). En pocas palabras, se basa en el número par más cercano al redondear a 5. Por lo tanto, no se pueden obtener números de coma flotante confiables utilizando DecimalForamt. Finalmente podemos considerar usar BigDecimal para cálculos más precisos:
BigDecimal proporciona múltiples constructores relacionados con números de punto flotante:
Copie el código de código de la siguiente manera:
BigDecimal(double val) Traduce un doble en BigDecimal.
BigDecimal(String val) Traduce la representación de cadena de un BigDecimal en un BigDecimal.
Sin embargo, el uso de parámetros dobles para crear objetos dará como resultado valores inexactos. Solo crear objetos a través de String es lo más preciso.
Por ejemplo:
Copie el código de código de la siguiente manera:
BigDecimal bd1=nuevo BigDecimal(0.05);
System.out.println(bd1.toString());
BigDecimal bd2=nuevo BigDecimal("0.05");
System.out.println(bd2.toString());
Obtenga el resultado:
0.05000000000000000277555756156289135105907917022705078125
0,05
Por lo tanto, en última instancia necesitamos usar String para crear objetos, para que los resultados obtenidos sean los más precisos. Además, si es un número doble, también podemos usar: BigDecimal.valueOf(double val). El código fuente JDK es el siguiente:
Copie el código de código de la siguiente manera:
valor BigDecimal estático público de (doble val)
{
devolver nuevo BigDecimal(Double.toString(val));
}
Lo último a tener en cuenta es: la suma, resta, multiplicación y división de BigDecimal en última instancia devuelven un nuevo objeto BigDecimal. Debido a que BigDecimal es inmutable, se generará un nuevo objeto durante cada operación, por lo que .add(b); Se realiza, a no guarda el valor después de la operación de suma. El uso correcto debe ser a=a.add(b).