определяются спецификацией IEEE 754 и уже перечислялись в лекции 3:
положительная и отрицательная бесконечности (positive/negative infinity);
значение 'не число', Not-a-Number, сокращенно NaN ;
положительный и отрицательный нули.
Все эти значения представлены как для типа float, так и для double.
Положительную и отрицательную бесконечности можно получить следующим образом:
1f/0f // положительная бесконечность, // тип float -1d/0d // отрицательная бесконечность, // тип double
Также в классах Float и Double определены константы POSITIVE_INFINITY и NEGATIVE_INFINITY. Как видно из примера, такие величины получаются при делении конечных величин на ноль.
Значение NaN можно получить, например, в результате следующих действий:
0.0/0.0 // деление ноль на ноль (1.0/0.0)0.0 // умножение бесконечности на ноль
Эта величина также представлена константами NaN в классах Float и Double.
Величины положительный и отрицательный ноль записываются очевидным образом:
0.0 // дробный литерал со значением // положительного нуля +0.0 // унарная операция +, ее значение - // положительный ноль -0.0 // унарная операция -, ее значение - // отрицательный ноль
Все дробные значения строго упорядочены. Отрицательная бесконечность меньше любого другого дробного значения, положительная – больше. Значения +0.0 и -0.0 считаются равными, то есть выражение 0.0==-0.0 истинно, а 0.0>-0.0 – ложно. Однако другие операторы различают их, например, выражение 1.0/0.0 дает положительную бесконечность, а 1.0/-0.0 – отрицательную.
Единственное исключение - значение NaN. Если хотя бы один из аргументов операции сравнения равняется NaN, то результат заведомо будет false (для оператора != соответственно всегда true ). Таким образом, единственное значение x, при котором выражение x!=x истинно,– именно NaN.
Возвращаемся к вопросу переполнения в числовых операциях. Если получаемое значение слишком велико по модулю ( overflow ), то результатом будет бесконечность соответствующего знака.
print(1e20f*1e20f); print(-1e200*1e200);
В результате получаем:
Infinity -Infinity
Если результат, напротив, получается слишком мал ( underflow ), то он просто округляется до нуля. Так же поступают и в том случае, когда количество десятичных знаков превышает допустимое:
print(1e-40f/1e10f); // underflow для float print(-1e-300/1e100); // underflow для double float f=1e-6f; print(f); f+=0.002f; print(f); f+=3; print(f); f+=4000; print(f);
Результатом будет:
0.0 -0.0 1.0E-6 0.002001 3.002001 4003.002
Как видно, в последней строке был утрачен 6-й разряд после десятичной точки.
Другой пример (из спецификации языка Java):
double d = 1e-305
Результатом будет:
3.141592653589793E-305 3.1415926535898E-310 3.141592653E-315 3.142E-320 0.0