Ответ 1
У конструктора BigDecimal (double) есть некоторые проблемы, предпочтительнее использовать BigDecimal (String) или BigDecimal.valueOf(double).
System.out.println(new BigDecimal(135.69)); //135.68999999999999772626324556767940521240234375
System.out.println(new BigDecimal("135.69")); // 135.69
System.out.println(BigDecimal.valueOf(135.69)); // 135.69
Документация BigDecimal (double) объясняет это поведение:
- Результаты этого конструктора могут быть несколько непредсказуемыми. Можно предположить, что запись нового BigDecimal (0.1) в Java создает BigDecimal, который в точности равен 0,1 (немасштабированное значение 1 со шкалой 1), но на самом деле оно равно 0,1000000000000000055511151231257827021181583404541015625. Это связано с тем, что 0,1 не может быть представлен точно как двойной (или, если на то пошло, как двоичная доля любой конечной длины). Таким образом, значение, которое передается конструктору, не точно равно 0,1, независимо от того, что происходит.
- Конструктор String, с другой стороны, совершенно предсказуем: запись нового BigDecimal ( "0.1" ) создает BigDecimal, который точно равен 0,1, как и следовало ожидать. Поэтому, как правило, рекомендуется использовать конструктор String для этого.
- Когда в качестве источника для BigDecimal следует использовать double, обратите внимание, что этот конструктор обеспечивает точное преобразование; он не дает того же результата, что и преобразование double в String с использованием метода Double.toString(double), а затем с использованием конструктора BigDecimal (String). Чтобы получить этот результат, используйте статический метод valueOf (double).