setscale round multiply decimals java bigdecimal

multiply - java bigdecimal round 2 decimals



BigDecimal-para usar new o valueOf (3)

Encontré dos formas de obtener el objeto BigDecimal de una doble d.

1. new BigDecimal(d) 2. BigDecimal.valueOf(d)

¿Cuál sería un mejor enfoque? ¿ValueOf crearía un nuevo objeto?

En general (no solo BigDecimal), ¿qué se recomienda - nuevo o valueOf?

Gracias.


Básicamente valueOf (doble val) simplemente hace esto:

return new BigDecimal(Double.toString(val));

Por lo tanto -> sip, se creará un nuevo objeto :).

En general creo que depende de tu estilo de codificación. No mezclaría valueOf y "new", si ambos tienen el mismo resultado.


Esas son dos preguntas separadas: "¿Qué debo usar para BigDecimal ?" y "¿Qué hago en general?"

Para BigDecimal : esto es un poco complicado, porque no hacen lo mismo . BigDecimal.valueOf(double) utilizará la representación de String canónica del valor double pasado para crear una instancia del objeto BigDecimal . En otras palabras: el valor del objeto BigDecimal será lo que verá cuando haga System.out.println(d) .

Sin embargo, si utiliza new BigDecimal(d) , BigDecimal intentará representar el valor double mayor precisión posible . Esto generalmente resultará en que se almacenen muchos más dígitos de los que desea. Estrictamente hablando, es más correcto que valueOf() , pero es mucho menos intuitivo.

Hay una buena explicación de esto en el JavaDoc:

Los resultados de este constructor pueden ser algo impredecibles. Se podría suponer que la escritura new BigDecimal(0.1) en Java crea un BigDecimal que es exactamente igual a 0,1 (un valor sin escala de 1, con una escala de 1), pero en realidad es igual a 0,1000000000000000055511151231257827021181583404541015625. Esto se debe a que 0.1 no se puede representar exactamente como un double (o, en realidad, como una fracción binaria de cualquier longitud finita). Por lo tanto, el valor que se pasa al constructor no es exactamente igual a 0.1, a pesar de las apariencias.

En general, si el resultado es el mismo (es decir, no en el caso de BigDecimal , pero en la mayoría de los otros casos), entonces debería preferirse valueOf() : puede hacer el almacenamiento en caché de valores comunes (como se ve en Integer.valueOf() ) e incluso puede cambiar el comportamiento de almacenamiento en caché sin tener que cambiar la persona que llama. new siempre creará una instancia de un nuevo valor, incluso si no es necesario (mejor ejemplo: new Boolean(true) vs. Boolean.valueOf(true) ).


Si está utilizando sus objetos BigDecimal para almacenar valores de moneda, entonces le recomiendo que NO incluya ningún valor doble en ninguna parte en sus cálculos.

Como se indicó en otra respuesta, existen problemas de precisión conocidos con valores dobles y estos volverán a atormentarlo a lo grande.

Una vez que superas eso, la respuesta a tu pregunta es simple. Siempre use el método constructor con el valor de Cadena como argumento para el constructor, ya que no hay un método valueOf para String .

Si quieres una prueba, prueba lo siguiente:

BigDecimal bd1 = new BigDecimal(0.01); BigDecimal bd2 = new BigDecimal("0.01"); System.out.println("bd1 = " + bd1); System.out.println("bd2 = " + bd2);

Obtendrás la siguiente salida:

bd1 = 0.01000000000000000020816681711721685132943093776702880859375 bd2 = 0.01

Vea también esta pregunta relacionada