Я должен вычислить некоторые переменные с плавающей точкой, и мой коллега предлагает мне использовать BigDecimal
вместо, double
так как это будет более точным. Но я хочу знать, что это такое и как извлечь из этого максимум BigDecimal
?
java
floating-point
double
bigdecimal
Чыонг Ха
источник
источник
Ответы:
A
BigDecimal
является точным способом представления чисел. АDouble
имеет определенную точность. Работа с двойными значениями различной величины (скажем,d1=1000.0
иd2=0.001
) может привести к0.001
полному падению при суммировании, поскольку разница в величине очень велика. СBigDecimal
этим бы не случилось.Недостатком
BigDecimal
является то , что он медленнее, и это немного сложнее программных алгоритмов , что путь (из - за+
-
*
и/
не перегружена).Если вы имеете дело с деньгами, или точность является обязательным, используйте
BigDecimal
. В противном случае,Doubles
как правило, достаточно хорошо.Я рекомендую читать Javadoc о ,
BigDecimal
как они объясняют вещи лучше , чем я здесь :)источник
if (Math.abs(loadPerServer - maxLoadPerServer) < 0.000001d) {
BigDecimal
», у Double будет больше «точности» (больше цифр).Мой английский не очень хороший, поэтому я просто напишу простой пример здесь.
Выход программы:
Кто-нибудь еще хочет использовать double? ;)
источник
System.out.println(0.003f - 0.002f);
BigDecimal является точным:System.out.println(new BigDecimal("0.003").subtract(new BigDecimal("0.002")));
Есть два основных отличия от двойного:
Причина, по которой вы должны использовать BigDecimal для денежных расчетов, заключается не в том, что он может представлять любое число, а в том, что он может представлять все числа, которые могут быть представлены в десятичном представлении и которые включают в себя практически все числа в денежном мире (вы никогда не переводите 1/3 $ кому-то).
источник
Если вы записываете дробное значение, такое
1 / 7
как десятичное значение, вы получитес бесконечной последовательностью
142857
. Поскольку вы можете записать только конечное число цифр, вы неизбежно внесете ошибку округления (или усечения).Числа, подобные
1/10
или1/100
выраженные в виде двоичных чисел с дробной частью, также имеют бесконечное количество цифр после десятичной точки:Doubles
хранить значения в двоичном виде и, следовательно, может привести к ошибке исключительно путем преобразования десятичного числа в двоичное число, даже не выполняя никакой арифметики.С
BigDecimal
другой стороны, десятичные числа (как ) сохраняют каждую десятичную цифру как есть. Это означает, что десятичный тип не является более точным, чем двоичный тип с плавающей запятой или тип с фиксированной запятой в общем смысле (т. Е. Он не может быть сохранен1/7
без потери точности), но он более точен для чисел с конечным числом десятичных разрядов, так как это часто бывает для расчета денег.У Java
BigDecimal
есть дополнительное преимущество, заключающееся в том, что он может иметь произвольное (но конечное) количество цифр с обеих сторон десятичной точки, ограниченное только доступной памятью.источник
BigDecimal - это числовая библиотека Oracle с произвольной точностью. BigDecimal является частью языка Java и полезен для самых разных приложений - от финансовых до научных (вот где я).
Нет ничего плохого в использовании двойников для определенных вычислений. Предположим, однако, что вы хотите вычислить Math.Pi * Math.Pi / 6, то есть значение дзета-функции Римана для реального аргумента два (проект, над которым я сейчас работаю). Деление с плавающей точкой ставит вас перед болезненной проблемой ошибки округления.
BigDecimal, с другой стороны, включает в себя множество опций для вычисления выражений с произвольной точностью. Методы добавления, умножения и деления, описанные в документации Oracle ниже, «заменяют» +, * и / в BigDecimal Java World:
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
Метод CompareTo особенно полезен в циклах while и for.
Однако будьте осторожны при использовании конструкторов для BigDecimal. Конструктор строк очень полезен во многих случаях. Например, код
BigDecimal onethird = new BigDecimal ("0.33333333333");
использует строковое представление 1/3 для представления этого бесконечно повторяющегося числа с заданной степенью точности. Ошибка округления, скорее всего, где-то так глубоко внутри JVM, что ошибки округления не будут мешать большинству ваших практических расчетов. Однако, по личному опыту, я видел, как округление приближается. В этом отношении метод setScale важен, как видно из документации Oracle.
источник
/* * Portions Copyright IBM Corporation, 2001. All Rights Reserved. */
Если вы имеете дело с расчетами, существуют законы о том, как вы должны рассчитывать и какую точность вы должны использовать. Если вам не удастся, вы будете делать что-то незаконное. Единственная реальная причина в том, что битовое представление десятичных регистров не является точным. Как сказал Бэзил, пример - лучшее объяснение. Просто чтобы дополнить его пример, вот что происходит:
Вывод:
Также у нас есть что:
Дает нам вывод:
Но:
Имеет выход:
источник