Кен Арнольд Джеймс Гослинг
Вид материала | Документы |
- Джеймс трефил, 41001.36kb.
- Джеймс А. Дискретная математика и комбинаторика [Текст] / Джеймс А. Андерсон, 42.79kb.
- Человеческая способность эти ценности производить и использовать; является важнейшей, 110.76kb.
- Джеймс блиш города в полете 1-4 триумф времени вернись домой, землянин жизнь ради звезд, 10495.38kb.
- Джеймс Н. Фрей. Как написать гениальный роман, 2872.12kb.
- Дп «авто интернешнл» Київ, вул. Урицького, 1а Тел. (044) 20-60-333 Факс. (044) 20-60-343, 82.44kb.
- Тема Кол-во страниц, 26.85kb.
- Тема Кол-во страниц, 56.3kb.
- Тема Кол-во страниц, 20.7kb.
- Арнольд И. В. Стилистика современного английского языка, 20.42kb.
5.15. Арифметические операторы
Java поддерживает семь арифметических операторов, которые работают с любыми числовыми типами:
+ сложение
- вычитание
* умножение
/ деление
% остаток
Java также поддерживает унарный минус (-) для изменения знака числа. Знак может быть изменен оператором следующего вида:
val = -val;
Кроме того, имеется и унарный плюс — например, +3. Унарный плюс включен для симметрии, без него было бы невозможно записывать константы вида +2.0.
5.15.1. Целочисленная арифметика
Целочисленная арифметика выполняется с дополнением по модулю 2 — то есть при выходе за пределы своего диапазона допустимых значений (int или long) величина приводится по модулю, равному величине диапазона. Таким образом, в целочисленной арифметике никогда не происходит переполнения, встречаются лишь выходы значения за пределы диапазона.
При целочисленном делении происходит округление по направлению к нулю (то есть 7/2 равно 3, а –7/2 равно –3). Деление и остаток для целых типов подчиняются следующему правилу:
(x/y)*y + x%y == x
Следовательно, 7%2 равно 1, а –7%2 равно –1. Деление на ноль или нахождение остатка от деления на 0 в целочисленной арифметике не допускается и приводит к запуску исключения ArithmeticException.
Арифметические операции с символами представляют собой целочисленные операции после неявного приведения char к типу int.
5.15.2. Арифметика с плавающей точкой
Для работы с плавающей точкой (как для представления, так и для совершения операций) в Java используется стандарт IEEE 7541985. В соответствии с ним допускаются как переполнение в сторону бесконечности (значение превышает максимально допустимое для double или float), так и вырождение в ноль (значение становится слишком малым и неотличимым от нуля для double или float). Также имеется специальное представление NaN (“Not A Number”, то есть “не-число”) для результатов недопустимых операций — например, деления на ноль.
Арифметические операции с конечными операндами работают в соответствии с общепринятыми нормами. Знаки выражений с плавающей точкой также подчиняются этим правилам; перемножение двух чисел с одинаковым знаком дает положительный результат, тогда как при перемножении двух чисел с разными знаками результат будет отрицательным.
Сложение двух бесконечностей с одинаковым знаком дает бесконечность с тем же знаком. Если знаки различаются — ответ равен NaN. Вычитание бесконечностей с одинаковым знаком дает NaN; вычитание бесконечностей с разными знаками дает бесконечность, знак которой совпадает со знаком левого операнда. Например, (-(-)) равно . Результат любой арифметической операции, в которой участвует величина NaN, также равен NaN. При переполнении получается бесконечность с соответствующим знаком, а при вырождении — ноль с соответствующим знаком. В стандарте IEEE имеется отрицательный ноль, который равен +0.0, однако 1f/0f равно положительной бесконечности, а 1f/-0f равно отрицательной бесконечности.
Если -0.0 == 0.0, как же отличить отрицательный ноль, полученный в результате вырождения, от положительного? Его следует использовать в выражении, в котором участвует знак, и проверить результат. Например, если значение x равно отрицательному нулю, то выражение 1/x будет равно отрицательной бесконечности, а если положительному — то положительной бесконечности.
Операции с бесконечностями выполняются по стандартным математическим правилам. Сложение (или вычитание) конечного числа с любой бесконечностью также дает бесконечность. Например, (-+x) дает - для любого конечного x.
Бесконечность может быть получена за счет соответствующей арифметической операции или использования имени бесконечности для объектов типа float или double: POSITIVE_INFINITY или NEGATIVE_INFINITY. Например, Double.NEGATIVE_INFINITY представляет значение отрицательной бесконечности для объектов типа double.
Умножение бесконечности на ноль дает в результате NaN. Умножение бесконечности на ненулевое конечное число дает бесконечность с соответствующим знаком.
Деление, а также деление с остатком может давать бесконечность или NaN, но никогда не приводит к исключениям. В таблице перечислены результаты арифметических операций при различных значениях операндов:
x | y | x/y | x%y |
Конечное | ±0.0 | | NaN |
Конечное | | ±0.0 | x |
±0.0 | ±0.0 | NaN | NaN |
| Конечное | | NaN |
| | NaN | NaN |
Во всех остальных отношениях нахождение остатка при делении с плавающей точкой происходит аналогично нахождению целочисленного остатка. Вычисление остатка методом Math.IEEERemainder описано в разделе 14.8.
5.15.3. Арифметика с плавающей точкой и стандарт IEEE-754
Арифметика с плавающей точкой в языке Java представляет собой подмножество стандарта IEEE-754-1985. Тем читателям, которым необходимо полное понимание всех связанных с этим аспектов, следует обратиться к спецификации языка Java “The Java Language Specification”. Вот краткая сводка ключевых отличий:
- Непрерываемая арифметика: в Java отсутствуют какие-либо исключения или иные события, сигнализирующие об исключительных состояниях в смысле IEEE: деление на ноль, переполнение, вырождение или потеря точности. В арифметике Java не предусмотрены какие-либо действия при появлении значения NaN.
- Округление: в арифметике Java происходит округление к ближайшему — неточный результат округляется к ближайшему представимому значению; при наличии двух одинаково близких значений предпочтение отдается тому, у которого младший бит равен 0. Это соответствует стандарту IEEE. Однако при преобразовании числа с плавающей точкой к целому в Java происходит округление по направлению к нулю. Java не допускает выбираемых пользователем режимов округления для вычислений с плавающей точкой: округления вверх, вниз или по направлению к нулю.
- Условные операции: в арифметике Java отсутствуют реляционные предикаты, которые бы реализовывали понятие упорядоченности, за исключением !=. Тем не менее все возможные случаи, кроме одного, могут быть смоделированы программистом с использованием существующих операций отношения и логического отрицания. Исключением является отношение “упорядочено, но не равно”, которое при необходимости может быть представлено в виде x
y.
- Расширенные форматы: арифметика Java не поддерживает никаких расширенных форматов, за исключением того, что double может выступать в качестве расширения формата с одинарной точностью. Наличие других расширенных форматов не является требованием стандарта.
- Расширенные форматы: арифметика Java не поддерживает никаких расширенных форматов, за исключением того, что double может выступать в качестве расширения формата с одинарной точностью. Наличие других расширенных форматов не является требованием стандарта.
5.15.4. Конкатенация строк
Оператор + может применяться для конкатенации строк. Приведем пример:
String boo = "boo";
String cry = boo + "hoo";
cry += "!";
System.out.println(cry);
А вот как выглядит результат работы:
boohoo!
Оператор + также используется для конкатенации объектов типа String со строковым представлением любого примитивного типа или объекта. Например, следующий фрагмент заключает строку в кавычки-“елочки” (guillemet characters), которые используются для цитирования во многих европейских языках:
public static String guillemete(String quote) {
return '"' + quote + '"';
}
Неявное преобразование примитивных типов и объектов в строки происходит лишь при использовании + или += в выражениях со строками — и нигде более. Например, методу, вызываемому с параметром типа String, нужно передавать именно String — вы не сможете передать объект или float и рассчитывать на его неявное преобразование.