Ответ 1
new BigDecimal(0.7)
имеет не 0,7.
Он представляет 0.6999999999999999555910790149937383830547332763671875 (точно).
Причиной этого является то, что литерал double
0.7
точно не равен 0.7.
Если вам нужны точные BigDecimal
значения, вы должны использовать конструктор String
(фактически все конструкторы, которые не принимают значения double
, будут работать).
Попробуйте new BigDecimal("0.7")
.
JavaDoc конструктора BigDecimal(double)
содержит некоторые связанные примечания:
Результаты этого конструктора могут быть несколько непредсказуемыми. Можно предположить, что запись
new BigDecimal(0.1)
в Java создает aBigDecimal
, которая в точности равна 0,1 (немасштабированное значение 1 со шкалой 1), но на самом деле оно равно 0,1000000000000000055511151231257827021181583404541015625. Это связано с тем, что 0,1 невозможно представить точно какdouble
(или, если на то пошло, как двоичную долю любой конечной длины). Таким образом, значение, которое передается конструктору, не точно равно 0,1, независимо от того, что происходит.Конструктор
String
, с другой стороны, вполне предсказуем: записьnew BigDecimal("0.1")
создаетBigDecimal
, которая в точности равна 0,1, как и следовало ожидать. Поэтому обычно рекомендуется использовать конструкторString
.Когда a
double
должен использоваться как источник дляBigDecimal
, обратите внимание, что этот конструктор обеспечивает точное преобразование; он не дает того же результата, что и преобразованиеdouble
вString
с помощью методаDouble.toString(double)
, а затем с помощьюBigDecimal(String)
конструктор. Чтобы получить этот результат, используйте методstatic
valueOf(double)
.
Итак, чтобы подвести итог: если вы хотите создать BigDecimal
с фиксированным десятичным значением, используйте конструктор String
. Если у вас уже есть значение double
, то BigDecimal.valueOf(double)
обеспечит более интуитивное поведение, чем использование new BigDecimal(double)
.