Класс 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) , мантисса, хранящаяся в объекте, окажется очень большой. Но при создании такого же объекта четвертым конструктором, BigDecimal («0.1») , мантисса будет равна просто 1.

В Классе переопределены методы doubleValue(), floatValue(), intValue(), longValue() .

Большинство методов этого класса моделируют операции с вещественными числами. Они возвращают объект класса BigDecimal . Здесь буква х обозначает объект класса BigDecimal , буква n — целое значение типа int , буква r — способ округления, одну из восьми перечисленных выше констант:

abs() — абсолютное значение объекта this ;

add(x) — операция this + х ;

divide(х, r) — операция this / х с округлением по способу ;

divide(х, n, r) — операция this / х с изменением порядка и округлением по способу ;

mах(х) — наибольшее из this и х ; 

min(x) — наименьшее из this и х ; 

movePointLeft(n) — сдвиг влево на n разрядов;

movePointRight(n) — сдвиг вправо на n разрядов;

multiply(х) — операция this * х ; 

negate() — возвращает объект с обратным знаком; 

scale() — возвращает порядок чисел; 

setscaie(n) — устанавливает новый порядок ;

setscaie(n, r) — устанавливает новый порядок п и округляет число при необходимости по способу ;

signumo — знак числа, хранящегося в объекте;

subtract(х) — операция this — х ;

toBiginteger() — округление числа, хранящегося в объекте;

unscaiedvalue() —возвращает мантиссу числа.

Листинг 4.4 показывает примеры использования этих методов.

 

Листинг 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.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»); 

   } 

}

Почему символ умножения — звездочка — заключен в кавычки? «Юниксоидам» это понятно, а для других дадим краткое пояснение.

Это особенность операционной системы, а не языка Java. Введенную с клавиатуры строку вначале просматривает командная оболочка (shell) операционной системы, а звездочка для нее — указание подставить на это место все имена файлов из текущего каталога. Оболочка сделает это, и интерпретатор Java получит от нее длинную строку, в которой вместо звездочки стоят имена файлов через пробел.

Звездочка в кавычках понимается командной оболочкой как обычный символ. Командная оболочка снимает кавычки и передает интерпретатору Java то, что надо.