Набор BigDecimal Масштаб и округление

143

В чем разница между этими двумя вызовами? (Есть ли?)

// 1.
new BigDecimal("3.53456").round(new MathContext(4, RoundingMode.HALF_UP));
// 2.
new BigDecimal("3.53456").setScale(4, RoundingMode.HALF_UP);
пользователь
источник
7
помимо принятых ответов ниже - setScale () создает новый объект BigDecimal - учитывая его неизменяемый класс
prash
10
@prash roundметод также возвращает новый экземпляр BigDecimal, потому что, как вы сказали, экземпляры неизменяемы.
daiscog

Ответы:

218

Один важный момент, который упоминается, но не рассматривается напрямую, - это разница между «точностью» и «масштабом» и то, как они используются в этих двух утверждениях. «точность» - это общее количество значащих цифр в числе. «Масштаб» - это количество цифр справа от десятичной точки.

Конструктор MathContext принимает в качестве аргументов только точность и RoundingMode, поэтому масштаб никогда не указывается в первом операторе.

setScale() очевидно, принимает масштаб в качестве аргумента, а также RoundingMode, однако точность никогда не указывается во втором выражении.

Если переместить десятичную запятую на одну позицию вправо, разница станет очевидной:

// 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
Дейл Питерс
источник
40
Re: «точность» - это общее количество цифр в числе ». Нет. Точность - это количество значащих цифр. Точность 0,000042M составляет 2.
Дэвид Дж.
3
См .: «точность»: подсчет цифр начинается с крайней левой ненулевой цифры точного результата. docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
Эдди
если «Точность - это количество значащих цифр», то почему точность 0,0000009 равна 2? это должно быть 1
Sanchi Girotra
1
Как устанавливается значение вашего BigDecimal? Как вы выводите значение (использование String.format () может скрыть значащие цифры)?
Дейл Питерс
1
@SanchiGirotra Точность - это «количество цифр в немасштабированном значении». Точность 2 при немасштабированном значении 90 и шкале 8 дает 0,0000009. Как и точность 1, немасштабированное значение 9 и шкала 7.
daiscog
52

Это действительно большая разница, о которой вы должны помнить. setScale действительно устанавливает масштаб вашего числа, тогда как round округляет ваше число до указанных цифр, НО он «начинается с крайней левой цифры точного результата», как указано в jdk. Итак, что касается вашего образца, результаты такие же, но вместо этого попробуйте 0,0034. Вот моя заметка об этом в моем блоге:

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

user817756
источник