Класс Big Decimal
Класс
BigDecimal
расположен В пакете
java.math
.
Каждый объект этого класса хранит два целочисленных значения: мантиссу вещественного числа в виде объекта класса
Biglnteger
, и неотрицательный десятичный порядок числа типа
int
.
Например, для числа 76.34862 будет храниться мантисса 7 634 862 в объекте класса
Biglnteger
, и порядок 5 как целое число типа
int
. Таким образом, мантисса может содержать любое количество цифр, а порядок ограничен значением константы
integer.MAX_VALUE
. Результат операции над объектами класса
BigDecimal
округляется по одному из восьми правил, определяемых следующими статическими целыми константами:
ROUND_CEILING
— округление в сторону большего целого;
ROUND_DOWN
— округление к нулю, к меньшему по модулю целому значению;
ROUND_FLOOR
— округление к меньшему целому;
ROUND_HALF_DOWN
— округление к ближайшему целому, среднее значение округляется к меньшему целому;
ROUND_HALF_EVEN
— округление к ближайшему целому, среднее значение округляется к четному числу;
ROOND_HALF_UP
— округление к ближайшему целому, среднее значение округляется к большему целому;
ROUND_UNNECESSARY
— предполагается, что результат будет целым, и округление не понадобится;
ROUND_UP
— округление от нуля, к большему по модулю целому значению.
В классе
BigDecimal
четыре конструктора:
BigDecimal (Biglnteger bi) —
объект будет хранить большое целое
bi,
порядок равен нулю;
BigDecimal (Biglnteger mantissa, int scale)
— задается мантиса
mantissa
и неотрицательный порядок
scale
объекта; если порядок
scale
отрицателен, возникает исключительная ситуация;
BigDecimal (double d)
— объект будет содержать вещественное число удвоенной точности
d
; если значение
d
бесконечно или
NaN
, то возникает исключительная ситуация;
BigDecimal (String val)
—
число задается строкой символов
val
, которая должна содержать запись числа по правилам языка Java.
При использовании третьего из перечисленных конструкторов возникает неприятная особенность, отмеченная в документации. Поскольку вещественное число при переводе в двоичную форму представляется, как правило, бесконечной двоичной дробью, то при создании объекта, например,
BigDecimal(0.1)
, мантисса, хранящаяся в объекте, окажется очень большой. Она показана на рис. 4.5. Но при создании такого же объекта четвертым конструктором,
BigDecimal ("0.1")
, мантисса будет равна просто 1.
В Классе переопределены методы
doubleValue(), floatValue(), intValue(), longValue()
.
Большинство методов этого класса моделируют операции с вещественными числами. Они возвращают объект класса
BigDecimal
. Здесь буква
х
обозначает объект класса
BigDecimal
, буква
n
— целое значение типа
int
, буква
r
— способ округления, одну из восьми перечисленных выше констант:
abs()
— абсолютное значение объекта
this
;
add(x)
— операция
this + х
;
divide(х, r)
— операция
this / х
с округлением по способу
r
;
divide(х, n, r)
— операция
this / х
с изменением порядка и округлением по способу
r
;
mах(х)
— наибольшее из
this
и
х
;
min(x)
— наименьшее из
this
и
х
;
movePointLeft(n)
— сдвиг влево на n разрядов;
movePointRight(n)
— сдвиг вправо на
n
разрядов;
multiply(х)
— операция
this * х
;
negate()
— возврзщает объект с обратным знаком;
scale()
— возвращает порядок числз;
setscaie(n)
— устзнавливает новый порядок
n
;
setscaie(n, r)
— устанавливает новый порядок п и округляет число при необходимости по способу
r
;
signumo
— знак числа, хранящегося в объекте;
subtract(х)
— операция
this - х
;
toBiginteger()
— округление числа, хранящегося в объекте;
unscaiedvalue()
—возвращает мантиссу числа.
Листинг 4.4 показывает примеры использования этих методов, а рис. 4.5 — вывод результатов.
Рис. 4.5.
Методы класса
BigDecimal
в программе
BigDecimalTest
Листинг 4.4.
Методы класса
BigDecimal
В программе
BigDecimalTest
import java.math.*;
class BigDecimalTest{
public static void main,( String [] args) {
BigDecimal x = new BigDecimal("-12345.67890123456789");
BigDecimal у = new BigDecimal("345.7896e-4");
BigDecimal z = new BigDecimal(new Biglnteger("123456789"),8);
System.out.println("|x| = " + x.abs());
System.out.println("x + у = " + x.add(y));
System.out.println("x / у = " + x.divide(y, BigDecimal.ROUND__DOWN));
System.out.println("х / у = " +
x.divide(y, 6, BigDecimal.ROUND_HALF_EVEN));
System.out.println("max(x, y) = " + x.max(y));
System.out.println("min(x, y) = " + x.min(y));
System.out.println("x « 3 = " * x.movePointLeft(3));
System.out.println("x » 3 = " + x.mpvePQintRight(3));
System.out.println("x * у = " + x.multiply(y));
System.out.println("-x = " + x.negate());
System.out.println("scale of x = " + x.scale());
System.out.println("increase scale of x to 20 = " + x.setScale(20));
System.out.println("decrease scale of x to 10 = " +
x.setScale (10, BigDecimal.ROUND_HALF__UP)) ;
System.out.println("sign(x) = " + x.signum());
System.out.println("x - у = " + x.subtract(y)};
System.out.println("round x = " + x.toBiglnteger());
System.out.println("mantissa of x = " + x.unscaledValue());
System.out.println("mantissa of 0.1 =\n= " +
new BigDecimal(0.1).unscaledValue()); } }
Приведем еще один пример. Напишем простенький калькулятор, выполняющий четыре арифметических действий с числами любой величины. Он работает из командной строки. Программа представлена в листинге 4.5, а примеры использования калькулятора — на рис. 4.6.
Листинг 4.5.
Простейший калькулятор
import Java.math.*;
class Calc{
public static void main(String[] args){
if (args.length < 3){
System.err.println("Usage: Java Calc operand operator operand");
return;
}
BigDecimal a = new BigDecimal(args[0]);
BigDecimal b = new BigDecimal(args[2]);
switch (args[l].charAt(0)){
case '+': System.out.println(a.add(b)); break;
case '-': System.out.println(a.subtract(b)); break;
case '*': System.out.println(a.multiply(b)); break;
case '/': System.out.println(a.divide(b,
BigDecimal.ROUND_HALF_EVEN)); break;
default : System.out.println("Invalid operator");
}
}
}
Почему символ умножения — звездочка — заключен на рис. 4.6 в кавычки? "Юниксоидам" это понятно, а для других дадим краткое пояснение.
Рис. 4.6.
Результаты работы калькулятора
Это особенность операционной системы, а не языка Java. Введенную с клавиатуры строку вначале просматривает командная оболочка (shell) операционной системы, а звездочка для нее — указание подставить на это место все имена файлов из текущего каталога. Оболочка сделает это, и интерпретатор Java получит от нее длинную строку, в которой вместо звездочки стоят имена файлов через пробел.
Звездочка в кавычках понимается командной оболочкой как обычный символ. Командная оболочка снимает кавычки и передает интерпретатору Java то, что надо.