Вещественных типов в Java два: float и double. Они характеризуются разрядностью, диапазоном значений и точностью представления, отвечающим стандарту IEEE 7541985 с некоторыми изменениями. К обычным вещественным числам добавляются еще три значения:
□ положительная бесконечность, выражаемая константой positive_infinity и возникающая при переполнении положительного значения, например в результате операции умножения 3.0*6e307 или при делении на нуль;
□ отрицательная бесконечность negative_infinity, возникающая при переполнении отрицательного значения, например в результате операции умножения -3.0*6e307 или при делении на нуль отрицательного числа;
□ "не число", записываемое константой NaN (Not a Number) и возникающее, например, при умножении нуля на бесконечность.
В главе 4 мы поговорим о них подробнее.
Кроме того, стандарт различает положительный и отрицательный нуль, возникающий при делении на бесконечность соответствующего знака, хотя сравнение 0.0 == -0.0 дает в результате истину, true.
Операции с бесконечностями выполняются по обычным математическим правилам.
Во всем остальном вещественные типы — это обычные вещественные значения, к которым применимы все арифметические операции и сравнения, перечисленные для целых типов. Характеристики вещественных типов приведены в табл. 1.4.
Знатокам C/C++
В языке Java взятие остатка от деления %, инкремент ++ и декремент — применяются и к вещественным типам.
| Таблица 1.4. Вещественные типы | |||
|---|---|---|---|
| Тип | Разрядность | Диапазон | Точность |
| float | 4 байта | 3,4x10-38 < |х| < 3,4x1038 | 7—8 цифр в дробной части |
| double | 8 байтов | 1,7х10“308 < |х| < 1,7x10308 | 17 цифр в дробной части |
Примеры определения вещественных типов:
float x = 0.001f, y = -34.789F; double z1 = -16.2305, z2;
Поскольку к вещественным типам применимы все арифметические операции и сравнения, целые и вещественные значения можно смешивать в операциях. При этом правило приведения типов дополняется такими условиями:
□ если в операции один операнд имеет тип double, то и другой приводится к типу
double;
□ иначе, если один операнд имеет тип float, то и другой приводится к типу float;
□ в противном случае действует правило приведения целых значений.
Простая операция присваивания (simple assignment operator) записывается знаком равенства (=), слева от которого стоит переменная, а справа — выражение, совместимое с типом переменной: x = 3.5, у = 2 * (x - 0.567) / (x + 2), b = x < y, bb = x >= y && b.
Операция присваивания действует так: выражение, стоящее после знака равенства, вычисляется и приводится к типу переменной, стоящей слева от знака равенства. Результатом операции будет приведенное значение правой части.
Операция присваивания имеет еще одно, побочное, действие: переменная, стоящая слева, получает приведенное значение правой части, старое ее значение теряется.
В операции присваивания левая и правая части неравноправны, нельзя написать 3.5 = x. После операции x = y изменится переменная x, став равной y, а после y = x изменится переменная y.
Кроме простой операции присваивания есть еще 11 составных операций присваивания (compound assignment operators): +=, -=, *=, /=, %=, &=, |=, Л=, <<=, >>=, >>>=. Символы запи
сываются без пробелов, нельзя переставлять их местами.
Все составные операции присваивания действуют по одной схеме:
x операция = a
эквивалентно
x = (тип x)(x операция a)
Напомним, что переменная ind типа short определена у нас со значением 1. Присваивание ind += 7.8 даст в результате число 8, то же значение получит и переменная ind. Эта операция эквивалентна простой операции присваивания ind = (short)(ind + 7.8).
Перед присваиванием, при необходимости, автоматически производится приведение типа. Поэтому:
byte b = 1;
b = b + 10; // Ошибка!
b += 10; // Правильно!
Перед сложением b + 10 происходит повышение b до типа int, результат сложения тоже будет типа int и, в первом случае, результат не может быть присвоен переменной b без явного приведения типа. Во втором случае перед присваиванием произойдет сужение результата сложения до типа byte.