BigDecimal setScale y round

140

¿Cuál es la diferencia entre estas dos llamadas? (¿Hay alguna?)

// 1.
new BigDecimal("3.53456").round(new MathContext(4, RoundingMode.HALF_UP));
// 2.
new BigDecimal("3.53456").setScale(4, RoundingMode.HALF_UP);
usuario
fuente
66
aparte de las respuestas aceptadas a continuación: setScale () crea un nuevo objeto de BigDecimal, dada su clase inmutable
prash
9
@prash, el roundmétodo también devuelve una nueva instancia de BigDecimal porque, como dijiste, las instancias son inmutables.
Daiscog

Respuestas:

212

Un punto importante al que se alude pero no se aborda directamente es la diferencia entre "precisión" y "escala" y cómo se usan en las dos afirmaciones. "precisión" es el número total de dígitos significativos en un número. "escala" es el número de dígitos a la derecha del punto decimal.

El constructor MathContext solo acepta precisión y RoundingMode como argumentos y, por lo tanto, la escala nunca se especifica en la primera instrucción.

setScale() obviamente acepta la escala como argumento, así como RoundingMode, sin embargo, la precisión nunca se especifica en la segunda declaración.

Si mueve el punto decimal un lugar a la derecha, la diferencia quedará clara:

// 1.
new BigDecimal("35.3456").round(new MathContext(4, RoundingMode.HALF_UP));
//result = 35.35
// 2.
new BigDecimal("35.3456").setScale(4, RoundingMode.HALF_UP);
// result = 35.3456
dale peters
fuente
38
Re: "" precisión "es el número total de dígitos en un número". No. La precisión es el número de dígitos significativos. La precisión de 0.000042M es 2.
David J.
2
Ver: "precisión": el recuento de dígitos comienza desde el dígito más a la izquierda del resultado exacto. docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
Eddy
si "Precisión es el número de dígitos significativos", ¿por qué la precisión de 0.0000009 viene como 2? debería ser 1
Sanchi Girotra
1
¿Cómo se establece el valor de su BigDecimal? ¿Cómo está generando el valor (el uso de String.format () podría ocultar dígitos significativos)?
Dale Peters
1
@SanchiGirotra La precisión es "el número de dígitos en el valor sin escala". Una precisión de 2 con un valor sin escala de 90 y una escala de 8 da 0.0000009. Al igual que una precisión de 1, un valor sin escala de 9 y una escala de 7.
daiscog
52

De hecho, hay una gran diferencia, que debe tener en cuenta. setScale realmente establece la escala de su número, mientras que round redondea su número a los dígitos especificados PERO "comienza desde el dígito más a la izquierda del resultado exacto" como se menciona en el jdk. Entonces, con respecto a su muestra, los resultados son los mismos, pero intente 0.0034 en su lugar. Aquí está mi nota al respecto en mi blog:

http://araklefeistel.blogspot.com/2011/06/javamathbigdecimal-difference-between.html

usuario817756
fuente