Множество значений, представимых в типах float, double и long double кроме обычных конечных значений содержит три специальных значения NaN, -Inf, Inf.
Значение NaN (Not-a-Number) используется для того, чтобы сигнализировать о том, что результат некоторой операции не может быть вычислен из-за неопределенностей различного рода.
Например, операция 0.0/0.0 даст результатом NaN.
На самом деле в вещественных типах представимо целое семейство значений NaN, дополнительная информация о конкретном NaN-значении может быть использована как код ошибки.
Все функции перевода из строкового представления в вещественное значение, такие как *scanf, strtod и т. п. распознают строку NAN (независимо от регистра букв) и возвращают значение NaN.
Все функции перевода из вещественного значения в строковое представление, такие как *printf распознают значение NaN и выводят его в виде строки nan.
Результат операции с числами с плавающей точкой, такой как сложение, умножение и т. д. равен NaN, если один из аргументов операции равен NaN.
Если один из операндов операции сравнения равен NaN, операции сравнения дают следующий результат:
== | 0 |
!= | 1 |
< | 0 |
<= | 0 |
> | 0 |
>= | 0 |
Чтобы проверить вещественное значение на принадлежность к классу NaN можно использовать функции fpclassify или isnan.
#include <math.h> //... if (fpclassify(value) == FP_NAN) { // значение value является NaN } // или другой вариант if (isnan(value)) { // значение value является NaN }
В силу свойств значения NaN мы будем полагать, что последовательность чисел с плавающей точкой не может быть упорядочена, если в ней содержится элемент NaN
Эти значения представляют результат "бесконечность" который может возникать при выполнениях различных операций с плавающей точкой.
Например, 1.0/0.0 дает результат Inf, а -1.0/0.0 дает результат -Inf.
Все функции перевода из строкового представления в вещественное значение, такие как *scanf, strtod и т. п. распознают строку [+|-]INF (независимо от регистра букв) и возвращают значение Inf с соответствующим знаком.
Все функции перевода из вещественного значения в строковое представление, такие как *printf распознают значение Inf и выводят его в виде строки inf с соответствующим знаком.
Значения Inf, -Inf в операциях сравнения ведут себя естественным образом, например, следующие условия истинны:
inf == inf !(inf != inf) inf >= inf inf <= inf !(inf > inf) !(inf < inf)
Значение Inf больше любого конечного значения, а значение -Inf меньше любого конечного значения.
Однако, обратите внимание, что
!(inf - inf == 0)Так как inf - inf дает в результате NaN.
Чтобы проверить вещественное значение на принадлежность к классу Inf можно использовать функции fpclassify или isinf.
#include <math.h> //... if (fpclassify(value) == FP_INFINITE) { // значение value является Inf (любого знака) } // или другой вариант if (isinf(value) < 0) { // значение value является -inf } if (isinf(value) > 0) { // значение value является +inf }
Множество значений вещественных чисел содержит два нуля: положительный и отрицательный. Когда в результате некоторых вычислений (например, при умножении или делении) получается нулевой результат, его знак вычисляется по обычным правилам и сохраняется. Поэтому в результате может получиться как обычное значение 0.0, так и отрицательное -0.0. Эти значения равны друг другу и, соответственно, больше всех отрицательных чисел и меньше всех положительных чисел.
Если при операции деления делитель равен нулю, то его знак учитывается при вычислении знака получающейся бесконечности. Таким образом, 1.0/-0.0 == -inf, -1.0/-0.0 == inf.