Таким образом, как и для целочисленных значений, явное выписывание в коде литералов, которые слишком велики ( overflow ) или слишком малы ( underflow ) для используемых типов, приводит к ошибке компиляции (см. лекцию 3). Если же переполнение возникает в результате выполнения операции, то возвращается одно из специальных значений.
Теперь перейдем к преобразованию типов. Если хотя бы один аргумент имеет тип double, то значения всех аргументов приводятся к этому типу и результат операции также будет иметь тип double. Вычисление будет произведено с точностью в 64 бита.
Если же аргументов типа double нет, а хотя бы один аргумент имеет тип float, то все аргументы приводятся к float, вычисление производится с точностью в 32 бита и результат имеет тип float.
Эти утверждения верны и в случае, если один из аргументов целочисленный. Если хотя бы один из аргументов имеет значение NaN, то и результатом операции будет NaN.
Еще раз рассмотрим простой пример:
print(1/2); print(1/2.);
Результатом будет:
0 0.5
Достаточно одного дробного аргумента, чтобы результат операции также имел дробный тип.
Более сложный пример:
int x=3; int y=5; print (x/y); print((double)x/y); print(1.0x/y);
Результатом будет:
0 0.6 0.6
В первый раз оба аргумента были целыми, поэтому в результате получился ноль. Однако поскольку оба операнда представлены переменными, в этом примере нельзя просто поставить десятичную точку и таким образом перевести вычисления в дробный тип. Необходимо либо преобразовать один из аргументов (второй вывод на экран), либо вставить еще одну фиктивную операцию с дробным аргументом (последняя строка).
Приведение типов подробно рассматривается в другой лекции, однако обратим здесь внимание на несколько моментов.
Во-первых, при приведении дробных значений к целым типам дробная часть просто отбрасывается. Например, число 3.84 будет преобразовано в целое 3, а -3.84 превратится в -3. Для математического округления необходимо воспользоваться методом класса Math.round(…).
Во-вторых, при приведении значений int к типу float и при приведении значений типа long к типу float и double возможны потери точности, несмотря на то, что эти дробные типы вмещают гораздо большие числа, чем соответствующие целые. Рассмотрим следующий пример:
long l=111111111111L; float f = l; l = (long) f; print(l);
Результатом будет:
111111110656
Тип float не смог сохранить все значащие разряды, хотя преобразование от long к float произошло без специального оператора в отличие от обратного перехода.
Для каждого примитивного типа существуют специальные вспомогательные классы-обертки (wrapper classes). Для типов float и double это Float и Double. Эти классы содержат многие полезные методы для работы с дробными значениями. Например, преобразование из текста в число.
Кроме того, класс Math предоставляет большое количество методов для операций над дробными значениями, например, извлечение квадратного корня, возведение в любую степень, тригонометрические и другие. Также в этом классе определены константы PI и основание натурального логарифма E.
Булев тип
Булев тип представлен всего одним типом boolean, который может хранить всего два возможных значения – true и false . Величины именно этого типа получаются в результате операций сравнения.
Над булевыми аргументами можно производить следующие операции:
операции сравнения (возвращают булево значение)
==, !=
логические операции (возвращают булево значение)
!
&, |, ^
&&, ||
оператор с условием ?:
оператор конкатенации со строкой +
Логические операторы && и || обсуждались в предыдущей лекции. В операторе с условием