Числовые классы
В каждом из шести числовых классов-оболочек есть статические методы преобразования строки символов типа
string
лредставляющей число, в соответствующий примитивный тип:
Byte.parseByte(), Double.parseDouble(), Float.parseFloat(), Integer.parselnt(), Long.parseLong(), Short.parseShort()
. Исходная строка типа
string
, как всегда в статических методах, задается как аргумент метода. Эти методы полезны при вводе данных в поля ввода, обработке параметров командной строки, т. е. всюду, где числа представляются строками цифр со знаками плюс или минус и десятичной точкой.
В каждом из этих классов есть статические константы
MAX_VALUE
и
MIN_VALUE
, показывающие диапазон числовых значений соответствующих примитивных типов. В классах
Double
и
Float
есть еще константы
POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN
, о которых шла речь в
главе 1,
и логические методы проверки
isNan()
,
isInfinite()
.
Если вы хорошо знаете двоичное представление вещественных чисел, то можете воспользоваться статическими методами
floatTointBits()
и
doubieToLongBits()
, преобразующими вещественное значение в целое. Вещественное число задается как аргумент метода. Затем вы можете изменить отдельные биты побитными операциями и преобразовать измененное целое число обратно в вещественное значение методами
intsitsToFioat()
и
longBitsToDouble()
.
Статическими методами
toBinaryString(), toHexString() и
toOctalString()
классов
integer
и
Long
можно преобразовать целые значения типов
int
и
long
, заданные как аргумент метода, в строку символов, показывающую двоичное, шестнадцатеричное или восьмеричное представление числа.
В листинге 4.1 показано применение этих методов, а рис. 4.2 демонстрирует вывод результатов.
Рис. 4.2.
Методы числовых классов ;
Листинг 4.1.
Методы числовых классов
class NumberTest{
public static void main(String[] args){
int i = 0;
short sh = 0;
double d = 0;
Integer kl = new Integer(55);
Integer k2 = new Integer(100);
Double dl = new Double(3.14);
try{
i = Integer.parselnt(args[0]);
sh = Short.parseShort(args[0]);
d = Double.parseDouble(args[1]);
dl = new Double(args[1]);
kl = new Integer(args[0]);
}catch(Exception e){}
double x = 1.0/0.0;
System.out.println("i = " + i) ;
System.outjprintln("sh - " + sh) ;
System.out.println("d. = " + d) ;
System.out.println("kl.intValue() = " + kl.intValue());
System.out.println("dl.intValue() '= "'+ dl.intValuei));
System.out.println("kl > k2? " + kl.compareTo(k2));
System.out.println ("x = " + x);
System.out.println("x isNaN? " + Double.isNaN(x));
System.out.println("x islnfinite? " + Double.islnfinite(x));
System.out.println("x == Infinity? " +
(x == Double.POSITIVE_INFINITY) );
System.out.println("d = " + Double.doubleToLongBits(d));
System.out.println("i = " + Integer.toBinaryString(i));
System.out.println("i = " + Integer.toHexString(i));
System.out.println("i = " + Integer.toOctalString(i));
}
}
Методы
parseint()
и конструкторы классов требуют обработки исключений, поэтому в листинг 4.1 вставлен блок
try{} catch(){}
. Обработку исключительных ситуаций мы разберем в главе 16.
Класс 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 то, что надо.
Класс Biglnteger
Все примитивные целые типы имеют ограниченный диапазон значений. В целочисленной арифметике Java нет переполнения, целые числа приводятся по модулю, равному диапазону значений.
Для того чтобы было можно производить целочисленные вычисления с любой разрядностью, в состав Java API введен класс
Biglnteger
, хранящийся в пакете
java.math
. Этот класс расширяет класс
Number
, следовательно, в нем переопределены методы
doubleValue(), floatValue(), intValue(), longValue()
. Методы
byteVaiue()
и
shortvalue()
не переопределены, а прямо наследуются от класса
Number
.
Действия с объектами класса
Biglnteger
не приводят ни к переполнению, ни к приведению по модулю. Если результат операции велик, то число разрядов просто увеличивается. Числа хранятся в двоичной форме с дополнительным кодом.
Перед выполнением операции числа выравниваются по длине распространением знакового разряда.
Шесть конструкторов класса создают объект класса
BigDecimai
из строки символов (знака числа и цифр) или из массива байтов.
Две константы —
ZERO
и
ONE
— моделируют нуль и единицу в операциях с объектами класса
Biglnteger
.
Метод
toByteArray()
преобразует объект в массив байтов.
Большинство методов класса
Biglnteger
моделируют целочисленные операции и функции, возвращая объект класса
Biglnteger
:
abs()
— возвращает объект, содержащий абсолютное значение числа, хранящегося в данном объекте
this
;
add(x)
— операция
this + х
;
and(x)
— операция
this & х
;
andNot(x)
— операция
this & (~х)
;
divide (x)
— операция
this / х
;
divideAndRemainder(х)
— возвращает массив из двух объектов класса
Biglnteger
, содержащих частное и остаток от деления
this
на
х
;
gcd(x)
— наибольший общий делитель, абсолютных, значений объекта
this
и аргумента
х
;
mах(х)
— наибольшее из значений объекта
this
и аргумента
х
;
min(x)
— наименьшее из значений объекта
this
и аргумента
х
;
mod(x)
— остаток от деления объекта
this
на аргумент метода
х
;
modinverse(x)
— остаток от деления числа, обратного объекту
this
, на аргумент
х
;
modPow(n, m)
— остаток от деления объекта
this
, возведенного в степень
n
, на
m
;
multiply (х)
—операция
this * х
;
negate()
— перемена знака числа, хранящегося в объекте;
not()
— операция
~this
;
оr(х)
— операция
this | х
;
pow(n)
— операция возведения числа, хранящегося в объекте, в степень
n
;
remainder(х)
—операция
this % х
;
shiftLeft (n)
—
операция
this « n
;
shiftRight (n)
— операция this » n;
signum()
— функция
sign (x)
;
subtract (x)
— операция
this - x
;
xor(x)
— операция
this ^ x
.
В листинге 4.3 приведены примеры использования данных методов, а рис. 4.4 показывает результаты выполнения этого листинга.
Рис. 4.4.
Методы класса
Biglnteger
в программе
BiglntegerTest
Листинг 4.3.
Методы класса Biglnteger в программе BiglntegerTest
import Java.math.Biglnteger;
class BiglntegerTest{
public static void main(String[] args){
Biglnteger a = new Biglnteger("99999999999999999") ;
Biglnteger b = new Biglnteger("88888888888888888888");
System.out.println("bits in a = " + a.bitLength());
System.out.println("bits in b = " + b.bitLengthO);
System.out.println("a + b = " + a.add(b));
System.out.println("a & b = " + a.and(b));
System.out.println("a & ~b = " + a.andNot(b));
System.out.println("a / b = " + a.divide(b));
Biglnteger[] r = a.divideAndRemainder(b);
System.out.println("a / b: q = " + r[0] + ", r = " + r[l]);
System.out.println("gcd(a, b) = " + a.gcd(b));
System.out.println("max(a, b) = " + a.max(b));
System.out.printin("min(a, b) = " + a.min(b));
System.out.println("a mod b = " + a.mod(b));
System.out.println("I/a mod b = " + a.modlnverse(b));
System.out.println("алп mod b = " + a.modPow(a, b));
System.out.println("a * b = " + a.multiply(b));
System.out.println("-a = " + a.negate());
System, out. println ("~a = " + a.not());
System.out.println("a | b = " + a.or(b));
System.out.println("а л 3 = " + a.pow(3));
System.out.println("a % b = " + a.remainder(b));
System.out.println("a « 3 = " + a.shiftLeft(3)};
System.out.println("a » 3 = " + a.shiftRight(3));
System.out.println("sign(a) = " + a.signum());
System.out.println("a - b = " + a.subtract(b));
System.out.println("а л b = " + a.xor(b));
}
}
Обратите внимание на то, что в программу листинга 4.3 надо импортировать пакет
Java.math
.
Класс Boolean
Это очень небольшой класс, предназначенный главным образом для того, чтобы передавать логические значения в методы по ссылке.
Конструктор
Boolean (String s)
создает объект, содержащий значение
true
, если строка
s
равна "
true
" в любом сочетании регистров букв, и значение
false
—
для любой другой строки.
Логический метод
booieanvalue()
возвращает логическое значение, хранящееся в объекте.
Класс Character
В этом классе собраны статические константы и методы для работы с отдельными символами.
Статический метод
digit(char ch, in radix)
переводит цифру ch системы счисления с основанием
radix
в ее числовое значение типа
int
.
Статический метод
forDigit(int digit, int radix)
производит обратное преобразование целого числа
digit
в соответствующую цифру (тип
char
) в системе счисления с основанием
radix
.
Основание системы счисления должно находиться в диапазоне от
Character.MIN_RADIX до Character.MAX_RADIX.
Метод
tostring()
переводит символ, содержащийся в классе, в строку с тем же символом.
Статические методы
toLowerCase()
,
touppercase(), toTitieCase()
возвращают символ, содержащийся в классе, в указанном регистре. Последний из этих методов предназначен для правильного перевода в верхний регистр четырех кодов Unicode, не выражающихся одним символом.
Множество статических логических методов проверяют различные характеристики символа, переданного в качестве аргумента метода:
isDef ined()
— выясняет, определен ли символ в кодировке Unicode;
isDigit()
— проверяет, является ли символ цифрой Unicode;
isidentifierignorable()
— выясняет, нельзя ли использовать символ в идентификаторах;
isisocontroi()
— определяет, является ли символ управляющим;
isJavaidentifierPart()
— выясняет, можно ли использовать символ в идентификаторах;
isjavaidentifierstart()
— определяет, может ли символ начинать идентификатор;
isLetter()
— проверяет, является ли символ буквой Java;
IsLetterOrDigit()
— Проверяет, является ли символ буквой или цифрой Unicode;
isLowerCase()
— определяет, записан ли символ в нижнем регистре;
isSpaceChar()
— выясняет, является ли символ пробелом в смысле Unicode;
isTitieCase()
— проверяет, является ли символ титульным;
isUnicodeldentifierPart()
— выясняет, можно ли использовать символ в именах Unicode;
isunicodeidentifierstart()
— проверяет, является ли символ буквой Unicode;
isUpperCase()
— проверяет, записан ли символ в верхнем регистре;
isWhitespace()
— выясняет, является ли символ пробельным.
Точные диапазоны управляющих символов, понятия верхнего и нижнего регистра, титульного символа, пробельных символов, лучше всего посмотреть по документации Java API.
Листинг 4.2 демонстрирует использование этих методов, а на рис. 4.3 показан вывод этой программы.
Листинг 4.2.
Методы класса
Character
в программе
CharacterTest
class CharacterTest{
public static void main(String[] args){
char ch = '9';
Character cl = new Character(ch);
System.out.println("ch = " + ch);
System.out.println("cl.charValue() = " +
c1.charValue());
System.out.println("number of 'A' = " +
Character.digit('A', 16}};
System.out.println("digit for 12 = " +
Character.forDigit(12, 16}};
System.out.printlnC'cl = " + cl.toString() );
System.out.println("ch isDefined? " +
Character.isDefined(ch));
System.out.println("ch isDigit? " +
Character.isDigit(ch));
System.out.println("ch isldentifierlgnorable? " +
Character.isldentifierlgnorable(ch));
System.out.println("ch isISOControl? " +
Character.isISOControl(ch));
System.out.println("ch isJavaldentifierPart? " +
Character.isJavaldentifierPart(ch));
System.out.println("ch isJavaldentifierStart? " +
Character.isJavaldentifierStart(ch));
System.out.println("ch isLetter? " +
Character.isLetter(ch));
System.out.println("ch isLetterOrDigit? " +
Character.isLetterOrDigit(ch));
System.out.println("ch isLowerCase? " +
Character.isLowerCase(ch));
System.out.println("ch isSpaceChar? " +
Character.isSpaceChar(ch));
System.out.println("ch isTitleCase? " +
Character.isTitleCase(ch));
System.out.println("ch isUnicodeldentifierPart? " +
Character.isUnicodeldentifierPart(ch));
System.out.println("ch isUnicodeldentifierStart? " +
Character.isUnicodeldentifierStart(ch));
System.out.println("ch isUpperCase? " +
Character.isUpperCase(ch));
System.out.println("ch isWhitespace? " +
Character.isWhitespace(ch)); } }
В класс
Character
вложены классы
Subset
и
UnicodeBlock
, причем класс
Unicode
и еще один класс,
inputSubset
, являются расширениями класса
Subset
, как это видно на рис. 4.1. Объекты этого класса содержат подмножества Unicode.
Рис. 4.3.
Методы класса Character в программе CharacterTest
Вместе с классами-оболочками удобно рассмотреть два класса для работы со сколь угодно большими числами.
Класс Class
Класс
Object
, стоящий во главе иерархии классов Java, представляет все объекты, действующие в системе, является их общей оболочкой. Всякий объект можно считать экземпляром класса
Object
.
Класс с именем
class
представляет характеристики класса, экземпляром которого является объект. Он хранит информацию о том, не является ли объект на самом деле интерфейсом, массивом или примитивным типом, каков суперкласс объекта, каково имя класса, какие в нем конструкторы, поля, методы и вложенные классы.
В классе
class
нет конструкторов, экземпляр этого класса создается исполняющей системой Java во время загрузки класса и предоставляется методом
getciass()
класса
object
, например:
String s = "Это строка";
Class с = s.getClass();
Статический метод
forName(string class)
возвращает объект класса
class
для класса, указанного в аргументе, например:
Class cl = Class.forName("Java,lang.String");
Но этот способ создания объекта класса
class
считается устаревшим (deprecated). В новых версиях JDK для этой цели используется специальная конструкция — к имени класса через точку добавляется слово
class
:
Class c2 = Java.lang.String.class;
Логические методы
isArray(), isIntetface(), isPrimitive()
позволяют уточнить, не является ли объект массивом, интерфейсом или примитивным типом.
Если объект ссылочного типа, то можно извлечь сведения о вложенных классах, конструкторах, методах и полях методами
getoeciaredciasses()
,
getdeclaredConstructors(), getDeclaredMethods(), getDeclaredFields()
, в виде массива классов, соответствейно,
Class, Constructor, Method, Field
. Последние три класса расположены в пакете
java.lang.reflect
и содержат сведения о конструкторах, полях и методах аналогично тому, как класс
class
хранит сведения о классах.
Методы
getClasses(), getConstructors(), getlnterfaces(), getMethods(), getFieids()
возвращают такие же массивы, но не всех, а только открытых членов класса.
Метод
getsuperciass()
возвращает суперкласс объекта ссылочного типа,
getPackage()
— пакет,
getModifiers()
— модификаторы класса В битовой форме. Модификаторы можно затем расшифровать методами класса
Modifier
из пакета
Java.lang.reflect
.
Листинг 4.6 показывает применение этих методов, а рис. 4.7 — вывод результатов
Листийс 4.6
tМетоды класса Class в программе ClassTest
import java.lang.reflect.*;
class ClassTest{
public static void main(String[] args)(
Class с = null, c1 = null, c2 = null;
Field[] fld = null;
String s = "Some string";
с = s.getClass();
try{
cl = Class.forName("Java.lang.String"); // Старый стиль
c2 = Java.lang.String.class; // Новый стиль
if (!c1.isPrimitive())
fid = cl.getDeclaredFields(); // Все поля класса String
}catch(Exception e){}
System.out.println("Class c: " + c);
System.out.println("Class cl: " + cl);
System,out.println("Class c2: " + c2);
System.out.printlnt"Superclass c: " + c.getSuperclass());
System.out.println("Package c: " + c.getPackageO);
System.out.printlnf"Modifiers c: " + c.getModifiers());
for(int i = 0; i < fid.length; i++)
System.out.println(fld[i]);
}
}
Методы, возвращающие свойства классов, вызывают исключительные ситуации, требующие обработки. Поэтому в программу введен блок
try{} catch() {}
. Рассмотрение обработки исключительных ситуаций мы откладываем до
главы 16.
Рис. 4.7.
Методы класса
Class
в программе
ClassTest