Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Технологии обработки информации на Java. Учебное пособие
.pdf
null-ссылка всегда может быть приведена к любому ссылочному ти-
пу путем расширяющей конверсии.
На практике программист может игнорировать null-тип и просто
считать, что null – это такой специальный литерал, который можно присвоить любому ссылочному типу.
2.2. Примитивные Типы данных и Значения
Примитивные типы данных языка Java предопределены настоящей
спецификацией, и в качестве имен им выделены ключевы
е слова:
ПримитивныйТип:
ЧисловойТип
boolean
ЧисловойТип:
ЦелочисленныйТип
ВещественныйТип
ЦелочисленныйТип: один из
byte short int long char
ВещественныйТип: один из
float double
Значения примитивных типов не могут иметь общего состояния
с другими примитивными значениями.
Числовые типы делятся на целочисленные типы и вещественные типы с плавающей точкой.
Целочисленные типы – это byte, short, int и long, чьи значения – это, соответственно, 8-, 16-, 32- и 64-битные знаковые целые числа, выраженные в дополненном коде, и char, чье значение – это 16-битное
беззнаковое целое число, представляющее собой UTF-16 кодовый юнит.
Вещественные типы с плавающей точ
кой – это float, чье значение
представляется в соответствии с требованиями на 32-битное вещественное
число стандарта IEEE 754, и double, чье значение представляется в соответствии с требованиями на 64-битное вещественное число стандарта IEEE 754.
Тип boolean имеет ровно два значения: true и false.
2.2.1. Цел
очисленные Типы и Значения
Значения целочисленных типов находятся в следующих диапазонах:
Для byte от -128 до 127 включительно.
Для short от -32768 до 32767 включительно.
Для int от -2147483648 до 2147483647 включительно.
11

Для long от -9223372036854775808 до -9223372036854775807
включительно.
Для char от '\u0000' до '\uffff', что в числах означает от 0 до
65535 включительно.
2.2.2. Операции над целочисленными значениями
Язык программирования Java предоставляет ряд операций, которые
могут выполняться над целочисленными значениями:
Операции сравнения, результатом которых является тип boolean:
o операции числового сравнения <, <=, > и >=
o операции числовой эквивалентности == и !=
Числовы
е операции, результатом которых является тип int или
long:
o унарный плюс и минус с использованием знаков + и –
o мультипликативные операторы *, / и %
o аддитивные операции + и –
o операция инкремента ++ как в префиксной, так и в постфиксной
способах записи;
o операция декремента -- как в префиксной так и в постфиксной
способах записи;
o операции знакового и беззнакового побитов
ого сдвига <<, >>
и >>>
o операция побитового отрицания ~
o числовые побитовые операции &, ^ и |
Условная операция ? :
Операция приведения, которая может преобразовать значение це-
лочисленного типа к значению любого другого числового типа.
Операция строковой конкатенации +, которая выполняется в том
случае, если один из операндов имеет целочисленный тип, а другой имеет
тип String. Эта о
перация преобразует числовой операнд к типу String
(выражая число в десятичной системе счисления), и затем формирует новый объект типа String, который является конкатенацией ранее имевшихся строк.
Другие полезные конструкторы, методы и константы определены
в классах Byte, Short, Integer, Long и Character.
Если любая числовая опер
ация, кроме операции побитового сдвига,
имеет, по меньшей мере, один операнд типа long, тогда операция выполняется с 64-битной точностью, и результат числовой операции будет иметь
тип long. В том случае, если второй оператор при этом имеет тип, отличный от long, то перед выполнением операции он будет расшир
long путем выполнения числового приведения.
12
ен до типа

В том случае, если целочисленная операция имеет операнды любых
других типов, кроме long, то операция выполняется с использованием
32-битной точности, а результатом выполнения числовой операции является тип int. Если любой из операндов имеет тип, отличный от int, то перед выполнением операции он должен быть расширен до int путем выполнения числового приведения.
Любое значени
е любого целочисленного типа может быть преобразовано к любому числовому типу, и аналогично, значение любого числового типа можно привести к целочисленному типу. Однако невозможно произвести преобразование между целочисленными типами и типом
boolean.
Числовые операции никоим образом не информируют о переполне-
нии или недополнении переменной.
Числов
ая операция может выбрасывать исключение в следующих
ситуациях:
Любая числовая операция может выбрасывать NullPointer
Exception в том случае, если для выполнения операции необходимо
произвести анбоксинг над ссылочной переменной, имеющей null в качестве значения.
Операция целочисленного деления / и операция получения остатка
от целочисленного деления % могут выбрасывать Arithmetic
Exception в то
м случае, если их правосторонний операнд имеет нулевое
значение.
Операции инкремента и декремента ++ и -- могут выбрасывать
OutOfMemoryError в том случае, если при выполнении операции требуется выполнение боксинга, но в памяти JVM недостаточно места для создания нового объекта.
Пример 2.2.2-1. Числовые операции
Программа состоит из следующего модуля компиляции:
class Test {
public static void main(String[] args) {
int i = 1000000;
System.out.println(i * i);
long l = i;
System.out.println(l * l);
System.out.println(20296 / (l - i));
}
}
В результате компиляции и выполнения данного кода на экран будет выведено
следующее:
-727379968
1000000000000
13

После чего на экране будет выведена информация о возникновении
ArithmeticException, так как в результатате вычисления выражения l-i, будет получен 0,
что приведет к ошибке целочисленного деления на ноль. Первое умножение выполняется с 32-битной точностью, в то время как второе умножение выполняется с 64-битной
точностью. Значение -727379968 – это десятичное значение нижних 32 бит математического значения 1000000000000, которое слишком велико для представления в 32 битах типа int.
2.2.3. Вещественные Типы, Форматы и Значения
Вещественные типы с плавающей точкой – это float и double, которые концептуально связаны с 32-битным форматом одинарной точности и
64-битным форматом двойной точности значений и операций так, как это
указано в ANSI/IEEE стандарте 754-1985, IEEE Standard for Binary
Floating-Point Arithmetic, (IEEE, New York).
Стандарт IEEE 754 включает в себя не только положительные и отрицательные числа, состоящие из знака и магнгитуды, но также положительного и отрицательного нулей, положительной и отри
цательной бесконечности и специального значения Не-Число (в англоязычной терминологии Not-a-Number, в дальнейшем будет использоваться аббревиатура NaN).
Значение NaN используется для представления результатов выполнения
некорректной операции, такой, как деление нуля на ноль. Константа NaN
для типов float и double доступна через классы-обертки: Float.NaN и Dou-
ble.NaN.
От каждой реализации языка программирования Java требуется под-
держка дв
ух стандартных наборов вещественных значений с плавающей
точкой, называемых набор вещественных значений (float value set) и удвоенный набор вещественных значений (double value set). Кроме того, реализация языка программирования Java может поддерживать набор значений
с расширенной экспонентой (extended-exponent value set) и набор значений
с удвоенно-расширенной экспонентой (double-extended-exponent value set).
Эти расширенные наборы значений могут, в конкретных обстоят
ельствах,
быть использованы вместо стандартных наборов значений в выражениях
типа float или double.
Конечное ненулевое значение, входящее в любой из этих наборов
K-1
(e-
-1
значений с вещественной точкой, может быть выражено в форме s*m*2
N+1)
, где s – это +1 или -1, m это положительное целое число меньшее, чем
N
; e – это целое число в диапазоне от E
2
min
= -(2
K-1
-2) – это E
max
=2
включительно, и где N и K – это параметры, которые зависят от конкретно
используемого набора значений. Некоторые наборы могут быть представлены более чем одним способом. К примеру, предположим, что значение v
в наборе значений может быть представлено в форме, использующей конкретные значения для s, m и e, тогда если m – это четное число, и e было
K-1
меньше че
м 2
, тогда m может быть сделано вдвое меньше и e увеличено
14

на 1, что позволяет создать второе представление для одного и того же
значения v. Представление в такой форме называется нормализованным,
N-1
если m ≥ 2
значение в наборе значений не может быть представлено так, что m ≥ 2
; иначе представление называется денормализованным. Если
N-1
то такое значение называется денормализованным, т.к. оно не имеет нормализованного представления
и E
Ограничения параметров N и К (и унаследованных параметров E
) для двух обязательных и двух дополнительных наборов веществен-
max
min
ных значений суммированы в табл. 2.1.
Таблица 2.1
Параметры для наборов значений
Параметр вещественный с расширенной
экспонентой
N 24 24 53 53
K 8 ≥ 11 11 ≥ 15
E
+127 ≥ +1023 +1023 ≥ +16383
max
E
-126 ≤ -1022 -1022 ≤ -16382
min
удвоенный
вещественный
с удвоенно-расширенной
экспонентой
Если реализация языка поддерживает один или оба расширенных
наборов значений, тогда для каждого поддерживаемого расширенного
набора значений существует специфичная, зависящая от реализации константа K, чье значение ограничивается табл. 2.1; это значение K, в свою
очередь, указывает значения E
min
и E
max
.
Каждый из четырех наборов значений включает не только конечные
ненулевые значения, описанные выше, но и значение NaN, а также и четыре специальных значения: положительный ноль, отрицательный ноль, положительная бесконечность и отрицательная бесконечность.
Отметим, что ограничения в табл. 2.1 разработаны такими, что каждый элемент вещественного набора значений – это одновременно и значение набора знач
ений с расширенной экспонентой, удвоенного набора вещественных значений и набора вещественных значений с удвоеннорасширенной экспонентой. По тому же принципу каждый элемент удвоенного набора вещественных значений – это одновременно и элемент набора
вещественных значений с удвоенно-расширенной экспонентой. Каждый
расширенный набор значений имеет больший диапазон значений экспонент, чем соответствующий стандартн
ый набор, но не может иметь боль-
шую точность.
Элементы вещественного набора значений – это в точности те значения, которые могут быть представлены с использованием одной вещественной точки, определенной стандартом IEEE-754. Элементами удвоенного вещественного набора значений являются в точности те значения, которые могут быть представлены с ис
пользованием одной удвоенной веще-
,
15

ственной точки, определенной стандартом IEEE-754. Отметим, однако, что
элементы набора значений с расширенной экспонентой и набора значений
с удвоенно-расширенной экспонентой, определенные здесь, не соответствуют значениям, которые представляются с использованием стандарта
на вещественные форматы с одинарной и двойной точностью стандарта
IEEE-754 соответственно.
Вещественный, вещественный с расширенной экспонентой, удвоенный вещественный и вещественный с удвоенно-расширенн
ой экспонентой
наборы значений не являются типами данных. Представление значений
типа float в некоторой конкретной реализации языка Java может быть корректно выполнено с использованием элементов вещественного набора значений. Однако, в некоторых особенных частях кода для специфической реализации языка Java вместо обычного набора значений может быть использован набор с расширенн
ой экспонентой. Точно таким же образом для
представления типа double будет верным использование удвоенного набора вещественных значений, но в некоторых частях кода специфическая реализация языка Java может использовать набор значений с удвоеннорасширенной экспонентой вместо обычного.
Весь вещественный набор значений, за исклюлчением NaN, упоря-
дочен в порядке возрастания от наименьшего к наибольшему зн
ачению.
Порядок следования значений следующий: начинается с отрицательной
бесконечности, далее отрицательные конечные ненулевые значения, отрицательный и положительный нули, затем конечные положительные ненулевые значения, и, наконец, положительная бесконечность.
Стандарт IEEE 754 допускает существование одновременно нескольких, различающихся между собой значений NaN для каждого из его форматов вещественных чисел, как обычных, так и удвоенных. Так же как
и кажд
ая аппаратная платформа возвращает самостоятельно определенный
битовый шаблон для значения NaN при его генерации, программист способен самостоятельно задать значение NaN, пользуясь разными битовыми
шаблонами, для отображения, к примеру, различной диагностической информации.
По большей части, платформа Java SE считает значение NaN кон-
кретного типа свернутым в одно каноничное значени
е, и таким образом,
данная спецификация обычно ссылается на NaN как на одно каноничное
значение.
Однако, в версии 1.3 платформы Java SE были представлены методы,
позволяющие программисту сделать различие между NaN значениями:
Float.floatToRawIntBits и Double.doubleToRawLongBits. Заинтересованный читатель
может обратиться к спецификации классов Float и Double для получения
дополнительной информации.
Положительный ноль и отрицательный ноль с точки зрения сравнения эквивалентны; таким образом, результат выражения 0.0 == -0.0 –
16

это true, а результат 0.0 > -0.0 – это false. Однако другие операции могут
различать положительный и отрицательные нули; к примеру, выражение
1.0 / 0.0 в результате дает значение положительной бесконечности, а выражение 1.0 / -0.0 в результате дает значение отрицательной бесконечности.
Значение NaN неупорядоченно, поэтому:
Операции числового сравнения <, <=, > и >= возвращают false
в том случае, если один или оба его операндов имеют значение NaN
(§15.20.1).
Операция эквивалентности == возвращает false в том случ
ае, если
любой из операторов имеют значение NaN. В частности, (x<y)==!(x>=y)
будет возвращать значение false в том случае, если x или y будут иметь
значение NaN.
Оператор неравенства != возвращает true, если любой из операн-
дов имеет значение NaN. В частности, x!=x равен true тогда, когда x имеет
значение NaN.
2.2.4. Операции над вещественными числами
Язык программирования Java предоставляет ряд операций, которые
могут выполняться над вещественными знач
ениями:
Операции сравнения, результатом которых является тип boolean:
o операции числового сравнения <, <=, > и >=
o операции числовой эквивалентности == и !=
Числовые операции, результатом которых является тип float или
double:
o унарный плюс и минус с использованием операций + и –
o мультипликативные операторы *, / и %
o аддитивные операц
ии + и –
o операция инкремента ++ как в префиксной, так и в постфиксной
способах записи;
o операция декремента -- как в префиксной так и в постфиксной
способах записи.
Условная операция ? :
Операция приведения, которая может преобразовать значение
вещественного типа к значению любого другого числового типа.
Операция строковой конкатенации +, которая выполняется в то
м
случае, если один из операторов имеет вещественный тип, а другой имеет
тип String, и преобразует числовой операнд к типу String, в десятичной
форме (без потери информации), и затем формирует новый объект типа
String, который является конкатенацией ранее имевшихся строк.
Другие полезные конструкторы, методы и константы определены
в классах Float, Double и Math.
17

Если любая бинарная числовая операция имеет, по меньшей мере,
один операнд вещественного типа, тогда вся операция вычисляется с использованием вещественного типа, даже если один из операндов целочисленный.
Если любая числовая операция имеет, по меньшей мере, один операнд типа double, тогда операция выполняется с использованием 64-битной
вещественной арифметики, и результат число
вой операции будет иметь
тип double. В том случае, если второй оператор при этом имеет тип, отличный от double, то перед выполнением операции он будет расширен до типа
double путем выполнения числового приведения.
В том случае, если вещественная операция имеет операнды любых
других типов, кроме double, то операция выполняется с использованием
32-битной точности, а результатом выполнения числовой операции является тип float. Если любой из операндов имеет тип, отличный от float, то перед выполнением операции он должен быть ра
сширен до float путем вы-
полнения числового приведения.
Любое значение любого вещественного типа может быть преобразовано к любому числовому типу и, аналогично, значение любого числового
типа мож
но привести к вещественному типу. Однако невозможно произве-
сти преобразование между вещественными типами и типом boolean.
Поведение операций на вещественных числах подчиняется требованиям стандарта IEEE 754 (за исключением операции получения остатка от деления). В частности, язык программирования Java требует поддержки денормализованных вещественных чисел стандарта IEEE 754
и gradual underflow, который упрощает подтверждение желаемых
свойств конкретного числового алгоритма. Вещественные оп
ерации не
используют «flush to zero», если вычисленный результат является денормализованным числом.
Язык программирования Java требует, чтобы вещественная арифметика вела себя так, как будто каждая вещественная операция округляет
свой вещественный результат до требуемой точности. Неточный результат
должен быть округлен до представимого значения, ближайшего к конечному точному результату; если два ближайших представимых значени
я
одинаково близки, то выбран должен быть тот, у которого наименьший
значимый бит равен нулю. Это округление стандарта IEEE-754, используемое по умолчанию, и известное, как округление к ближайшему.
Язык программирования Java использует округление к нулю при
конвертировании вещественного значения к целому числу, которое действует в этом случае так, как будто число было просто обрезано, откидывая биты мантиссы. Округление к нул
ю в качестве результата выбирает
значение формата ближайшее и не большее по значению, чем бесконечно
точный результат
18

Вещественная операция, результатом которой является переполне-
ние, будет возвращать знаковую бесконечность.
Вещественная операция, результатом которой является underflow,
будет возвращать денормализованное значение или знаковый ноль.
Не определенная математически вещественная операция возвращает
NaN.
Вещественная операция может выбрасывать исключение в следую-
щих ситуациях:
любая вещественная операция может выбрасывать NullPointerEx-
ception в том случае, если для выполнения операции необходимо п
роизве-
сти анбоксинг над null-ссылкой;
операции инкремента и декремента ++ и -- могут выбрасывать
OutOfMemoryError в том случае, если при выполнении операции требуется
выполнение боксинга, и в памяти JVM недостаточно места для создания
нового объекта.
Пример 2.2.4-1. Вещественные операции
Программа состоит из следующего модуля компиляции:
class Test {
public static void main(String[] args) {
//пример переполнения:
double d=1e308
System.out.print("переполнение возвращает бесконеч-
ность: ");
System.out.println(d + "*10==" + d*10);
//пример gradual underflow:
d=1e-305 * Math.PI;
System.out.print("gradual underflow: " + d +"\n ");
for (int i = 0; i < 4; i++)
System.out.print(" " + (d /= 100000));
System.out.println();
// Пример получения NaN:
System.out.print("0.0/0.0 это Не-Число: ");
d = 0.0/0.0;
System.out.println(d);
// Пример неточного результата и округления:
System.out.print("неточный результат с типом
float:");
for (int i = 0; i < 100; i++) {
float z = 1.0f / i;
if (z * i != 1.0f)
System.out.print(" " + i);
}
System.out.println();
// Другой пример неточного результата и округления:
System.out.print("неточный результат с типом
double:");
19

for (int i = 0; i < 100; i++) {
double z = 1.0 / i;
if (z * i != 1.0)
System.out.print(" " + i);
}
System.out.println();
// Пример преобразования к целому числу с округле-
нием:
System.out.print("преобразование к int с округлени-
ем к 0: ");
d = 12345.6;
System.out.println((int)d + " " + (int)(-d));
}
}
результат компиляции и выполнения данного кода следующий:
переполнение возвращает бесконечность:
1.0e+308*10==Infinity
gradual underflow: 3.141592653589793E-305
3.1415926535898E-310 3.141592653E-315 3.142E-320
0.0
0.0/0.0 это Не-Число: NaN
неточный результат с типом float: 0 41 47 55 61 82
83 94 97
неточный результат с типом double: 0 49 98
преобразование к int с округлением к 0: 12345 -
12345
Этот пример демонстрирует, среди прочего, что в результате gradual underflow
может быть получено gradual loss of precision.
Результаты при i равном 0 включают в себя деление на ноль, так что z становит-
ся положительной бесконечностью, и z*0 это NaN, что не равно 1.0
2.2.5. Тип boolean и Логические Значения
Тип boolean представляет логическую величину с двумя возможны-
ми значениями, демонстрируемыми литералами true и false.
Логические операции – это:
Операции равенства и неравенства == и !=
Операция логического отрицания !
Логические операции &, ^ и |
Операции условное-И и условное-ИЛИ && и ||
Условная операция ? :
Операция строковой конкатенации +, которая выполняется в то
случае, если один из операторов имеет тип boolean, а другой имеет тип
String, и преобразует boolean операнд к типу String (это будет строка либо
"true" либо "false"), и затем формирует новый объект типа String, который
является конкатенацией ранее имевшихся строк.
20
м
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
