Это связано с тем, как хранится BigDecimal.Он использует шкалу для запоминания количества десятичных знаков.
unscaledValue и scale
Большие десятичные числа могут помнить количество десятичных знаков (мест после десятичного разделителя), которое оно имеет.Для этого они сохраняются в виде двух значений:
- и unscaledValue (обычно это BigInteger, но для небольших значений это тоже может быть long), которое содержит (значительный) цифры и
- a масштаб ( минус степень 10 для умножения unscaledValue на, чтобы получить номинальное значение , то есть вид отрицательного показателя).
Примеры: значение 1.0 хранится в виде UnscaledValue (я назову его UV) 10 и шкалы 1 ( 10 x 10 -1 ).Значение 3.000 сохраняется как УФ 3000 и шкала 3 ( 3000 x 10 -3 ), 12.34 как УФ= 1234 и шкала = 2 (т. Е. 1234 x 10 -2 ) и т. Д.
Ваше значение 10 сохраняется как UV = 10 и масштаб = 0 (кратко: UV = 10, s = 0).Но если вы удаляете конечные нули, вы конвертируете, например, 1.000 (UV = 1000, S = 3), вы удаляете пробные нули из UV и соответственно корректируете масштаб, чтобы он стал (UV = 1, S= 0): УФ теряет 3 нуля, шкала настраивается на 0.
Можно также использовать отрицательные шкалы , чтобы обозначить ( положительная ) степень 10.значение 2e20 сохраняется как UV = 2, с = -20 ( 2 x 10 20 ), а не как UV = 200000000000000000000, с = 0.Это экономит много места.Точно так же 2.00e20 сохраняется как UV = 200, с = -18 или 200 x 10 18 .
. Поэтому,при удалении конечных нулей 10 становится UV = 1, с = -1 ( 1 x 10 1 ) вместо UV = 10, s = 0( 10 x 10 0 ).И 6000 (УФ = 6000, с = 0) становится 6Е + 3 (УФ = 6, с = -3; 6 х 10 3 ).
Установка шкалы
Но вы можете легко установить шкалу обратно на 0 без изменения номинального значения.Если шкала была отрицательной, округление не произойдет.
BigDecimal b1 = new BigDecimal("10.000"); // UV=10000, s=3, 10000 x 10**-3
System.out.println(b1);
b1 = b1.stripTrailingZeros(); // UV=1, s=-1, *all* trailing zeros removed,
// as desired: 10000 --> 1
System.out.println(b1);
b1 = b1.setScale(0); // UV=10, s=0
System.out.println(b1);
Вывод:
10.000
1E+1
10
Чтобы удалить только конечные десятичные нули, выполните:
b1 = b1.stripTrailingZeros();
if (b1.scale() < 0)
b1 = b1.setScale(0);