1. Введение
Чтобы одолжить слова из книги «Эффективная Java», основные проектные цели плавания и двойных типов предназначены для научных вычислений и инженерных вычислений. Они выполняют бинарные операции с плавающей запятой, которые тщательно разработаны, чтобы обеспечить более точное быстрое приближение к широкому численному диапазону. Тем не менее, они не дают совершенно точных результатов и не должны использоваться в ситуациях, когда требуются точные результаты. Тем не менее, коммерческие расчеты часто требуют точных результатов, и Bigdecimal в настоящее время пригодится.
2. Введение в BigDecimal
BigDecimal состоит из целочисленного немасштабного значения любой точной и 32-разрядной целочисленной шкалы. Если он нулевой или положительный, шкала - это количество цифр после десятичной точки. Если это отрицательное число, умножьте немасштабное значение числа на отрицательную масштабную мощность 10. Следовательно, значение, представленное BigDecimal, составляет (UnscaledValue × 10-Scale).
3. Тестовый код
3.1 Конструктор (основные типы параметров теста являются двумя общими конструкторами с двойной и строкой)
Кода кода следующая: BigDecimal Adouble = new BigDecimal (1.22);
System.out.println («Конструкция с двойным значением:« + adouble);
BigDecimal Astring = New BigDecimal ("1.22");
System.out.println («Построить со строковым значением:" + arsting);
Как вы думаете, что будет результатом? Если вы не думаете, что первый выведет 1.22, то правильно поздравляю с ответом, результат вывода заключается в следующем:
Скопируйте код следующим образом: Construct с DoubleValue: 1.2199999999999999999733546474089962430298328399658203125
Построить с помощью строкового значения: 1.22
Описание JDK:
1. Результаты метода построения с двойным типом параметров непредсказуемы. Some people might think that the BigDecimal created by writing newBigDecimal(0.1) in Java is exactly equal to 0.1 (non-scaling value 1, whose scale is 1), but it is actually equal to 0.10000000000000000000000055511151231257827021181583404541015625. Это связано с тем, что 0,1 не может быть выражено точно как двойное (или для этого случая он не может быть выражен как любая бинарная десятичная десятичная конечная длины). Таким образом, значение, передаваемое в метод строительства, не будет точно равным 0,1 (хотя оно является равной этим значением).
2. С другой стороны, метод строительства строки полностью предсказуем: написание NewBigDecimal («0,1») создаст большую значимость, что точно равно ожидаемому 0,1. Следовательно, для сравнения, обычно рекомендуется сначала использовать строковый конструктор.
3. Когда двойник должен использоваться в качестве источника BigDecimal, обратите внимание, что этот конструктор обеспечивает точное преобразование; Он не дает того же результата, что и следующие операции: сначала используйте метод Double.toString (Double), а затем используйте конструктор BigDecimal (String) для преобразования двойного в строку. Чтобы получить результат, используйте метод статического значения (двойного).
3.2 Операция дополнения
Кода -копия выглядит следующим образом: BigDecimal a = new BigDecimal ("1.22");
System.out.println («Построить со строковым значением:" + a);
BigDecimal B = новый BigDecimal ("2,22");
A.Add (b);
System.out.println ("Aplus b IS:" + a);
Легко думать, что он будет выводить:
Скопируйте код следующим образом: построить с помощью StringValue: 1.22
A Plus B: 3,44
Но на самом деле плюс B: 1,22
4. Анализ исходного кода
4.1 Значение (DoubleVal) Метод
Скопируйте код следующим образом: Public Static BigDecimal Valueof (Double Val) {
// напоминание: нулевой двойной возврат '0,0', поэтому мы не можем
// использовать постоянный ноль. Это может быть достаточно важно, чтобы
// Оправдание заводского подхода, кеша или нескольких частных
// Константы, позже.
returnnew bigdecimal (double.toString (val)); // См. Третья точка в 3.1 о описании JDK
}
4.2 Метод добавления (BigDecimal Augend)
public BigDecimal Add (BigDecimal Agend) {long xs = this.intcompact; // BigDecimal, представленная целочисленным числом, например, A имеет значение IntCompact 122 Long YS = Augend.intCompact; // То же, что и выше, как выше BigInteger fst = (this.intCompact! = Раздут)? NULL: This.intval; // Инициализируется значение BigInteger, натуральное значение. ! = Раздутый)? NULL: AUGEND.INTVAL; int rscale = this.scale; // Десятичные места Long Sdiff = (Long) rscale - Augend.Scale; // Разница между десятичными местами, если (sdiff! = 0) {// Десятичные места с наиболее десятичными местами являются результатом, если (sdiff <0) {int rais = checklescale (-sdiff); rscale = Augend.Scale; if (xs == voldated || (xs = longmultiplypowerten (xs, raise)) == volted) fst = bigmultiplypowerten (rais); } else {int Raise = Augend.CheckScale (sdiff); if (ys == надутый || (ys = longmultiplypowerten (ys, raise)) == villated) snd = Augend.bigmultiplyPowerten (rais); }} if (xs! = villated && ys! = villated) {long sum = xs + ys; if ((((sum ^ xs) & (sum ^ ys)))> = 0l) // судить, есть ли переполнение. Return bigdecimal.valueof (sum, rcale); // Возврат BigDecimal экземпляр, полученный с использованием статического метода фабрики BigDecimal} if (fst == null) fst = bigInteger.valueof (xs); // Статический метод фабрики Biginteger if (snd = null) snd = biginteger.value (ys); BigInteger sum = fst.add (snd); return (fst.signum == snd.signum)? Новый Bigdecimal (sum, надутый, rcale, 0): новый Bigdecimal (sum, compactvalfor (sum), rcale, 0); // Возврат большего взыскания, полученный другими методами строительства}Выше приведено только анализ исходного кода с добавлением. Вычитание, умножение и деление фактически возвращают новый BigDecimal объект. Поскольку Biginteger и Bigdecimal являются неизменными, при выполнении каждого этапа операции генерируется новый объект, так что A.Add (B); Хотя операция добавления выполняется, A не сохраняет значение после операции добавления. Правильное использование должно быть a = a.add (b);
5. Резюме
(1) Коммерческие расчеты используют BigDecimal.
(2) Попробуйте использовать конструкторы со строкой типа параметра.
(3) Бигдецималы неизменны. При выполнении каждого этапа работы будет сгенерирован новый объект. Следовательно, при выполнении сложения, вычитания, умножения и деления вы должны сохранить значение после операции.
(4) Мы часто склонны игнорировать некоторые детали реализации базового JDK, что приводит к ошибкам, поэтому нам нужно уделять больше внимания.
Ссылка: класс BigDecimal