Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3 - Лексические структуры языка. Типы данных. И...docx
Скачиваний:
9
Добавлен:
19.11.2019
Размер:
93.32 Кб
Скачать

6.6 Не используйте числа с плавающей точкой для точных значений

Некоторые нецелые значения, например десятичные дроби в стоимостном выражении (долларо-центы), требуют точности. Числа с плавающей точкой не являются точными, и манипулирование ими приведет к ошибкам округления. В общем, не очень хорошо использовать плавающую точку для представления таких точных величин, как денежные суммы. Использование плавающей точки для вычислений стоимости является решением данной проблемы. Числа с плавающей точкой лучше всего приберечь для таких значений, например измерения, где величины являются изначально неточными.

6.7 Большие десятичные дроби для маленьких чисел

С появлением JDK 1.3 разработчики Java получили альтернативу для нецелых чисел: BigDecimal. BigDecimal является стандартным классом, без специальной поддержки в компиляторе, для представления двоичных чисел произвольной разрядности и выполнения арифметических действий над ними. По сути дела BigDecimal представлен как недифференцированное значение произвольной разрядности и коэффициент масштабирования, который указывает насколько сдвинуть влево десятичную точку для получения значения, разбитого на дробную и целую части. Итак, число, представленное BigDecimal является unscaledValue*10-scale .

Арифметические действия над значениями BigDecimal реализуются с помощью методов для сложения, вычитания, умножения и деления. Поскольку объекты BigDecimal являются неизменяемыми, то каждый из этих методов производит новый объект BigDecimal. В итоге BigDecimal не слишком хорошо подходит для интенсивных вычислений из-за затрат на создание объекта, но он спроектирован для представления точных десятичных чисел. Если Вам необходимо представить такие точные величины как денежные суммы, то BigDecimal прекрасно подойдет для этой задачи.

6.8 Все методы сравнения не созданы равными

Как и у всех типов с плавающей точкой, у BigDecimal тоже есть несколько особенностей. А именно, будьте осторожны с использованием метода equals() для проверки тождественности чисел. Два значения BigDecimal, представляющих одно и то же число, но имеющих различные коэффициенты масштабирования (например, 100.00 и 100.000) не будут равными при использовании метода equals(). Тем не менее, метод compareTo() будет считать их равными, а, следовательно, Вы должны использовать compareTo() вместо equals() при количественном сравнении двух значений BigDecimal.

Существуют некоторые случаи, когда для получения точных результатов недостаточно двоичной арифметики с произвольной разрядностью. Например, деление 1 на 9 выдает бесконечную периодическую двоичную дробь .111111... По этой причине BigDecimal позволяет Вам явно контролировать округление при выполнении операций деления. Точное деление на показатель степени 10 поддерживается методом movePointLeft().

6.9 Используйте BigDecimal в качестве типа обмена

В SQL-92 есть тип данных DECIMAL, который является точным числовым типом для представления десятичных чисел с фиксированной точкой и выполняет основную арифметическую операцию над двоичными числами. В некоторых диалектах SQL предпочитают называть этот тип NUMERIC, а другие также содержат тип данных MONEY, который определяется как десятичное число с двумя знаками справа от десятичной дроби.

Если Вы хотите сохранить число в поле DECIMAL в базе данных или извлечь значение из поля DECIMAL, то как можно убедиться в том, что число будет передано точно? Вы не хотите использовать методы setFloat() и getFloat(), обеспечиваемые JDBC классами PreparedStatement и ResultSet, поскольку конвертация из числа с плавающей точкой в десятичное число может привести к потере точности. Вместо этого, используйте setBigDecimal() и getBigDecimal() методы PreparedStatement и ResultSet.

Аналогично, XML-инструменты привязки данных, например, Castor, сгенерируют механизмы получения и установки для десятичных атрибутов и элементов (которые поддерживаются в качестве основного типа данных в XSD-схеме), используя BigDecimal.