BigDecimal-использовать new или valueOf
я столкнулся с двумя способами получения BigDecimal объекта из двойного d.
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
какой подход был бы лучше? Бы стоимость создания нового объекта?
В общем (не только BigDecimal), что рекомендуется - new или valueOf?
спасибо.
3 ответа:
это два отдельных вопроса: "Что я должен использовать
BigDecimal
?"и "что мне делать вообще?"на
BigDecimal
: Это немного сложно, потому что они не делай то же самое.BigDecimal.valueOf(double)
использовать canonicalString
представление наdouble
значение, переданное для создания экземпляра , потомBigDecimal
попытается представитьdouble
стоимостью как можно более точно. Это будет обычно результат в гораздо больше цифр хранятся, чем вы хотите. Строго говоря, это более правильно, чемvalueOf()
, но это гораздо менее интуитивно.есть хорошее объяснение этого в JavaDoc:
результаты этого конструктора можно несколько непредсказуемо. Можно предположить, что писать!--12--> в Java создает
BigDecimal
который точно равен 0.1 (значение без шкалы 1, со шкалой 1), но на самом деле он равен 0.1000000000000000055511151231257827021181583404541015625. Это связано с тем, что 0.1 не может быть представлен точно какdouble
(или, если на то пошло, как двоичная дробь из любой конечной длины). Таким образом, значение, которое передается в конструктор, не точно равно 0.1, внешний вид несмотря на.в общем, если результат тот же (т. е. не в случае
BigDecimal
, но и в большинстве других случаев), тоvalueOf()
должно быть предпочтительным: он может делать кэширование общих значений (как видно наInteger.valueOf()
) и он может даже изменить поведение кэширования без необходимости изменения вызывающего абонента.new
будет всегда создать экземпляр нового значения, даже если это не обязательно (лучший пример:new Boolean(true)
иBoolean.valueOf(true)
).
если вы используете
BigDecimal
объекты для хранения значений валют, то я настоятельно рекомендую вам сделать не включить любые двойные значения в любом месте в своих расчетах.как указано в другом ответе, есть известные проблемы точности с двойными значениями, и они вернутся, чтобы преследовать вас большое время.
как только вы пройдете мимо этого, ответ на ваш вопрос прост. Всегда используйте метод конструктора со строковым значением в качестве аргумента конструктор, как нет
valueOf
методString
.если вы хотите доказательств, попробуйте следующее:
BigDecimal bd1 = new BigDecimal(0.01); BigDecimal bd2 = new BigDecimal("0.01"); System.out.println("bd1 = " + bd1); System.out.println("bd2 = " + bd2);
вы получите следующий результат:
bd1 = 0.01000000000000000020816681711721685132943093776702880859375 bd2 = 0.01
см. также вопрос