Согласно стандарту языка C++, способ представления типов с плавающей точкой (floating-point types) определяется реализацией. Можно воспользоваться статическим членом is_iec559
шаблонного класса std::numeric_limits
для проверки соответствия некоторого типа стандарту IEEE 754-2008:
std::numeric_limits<double>::is_iec559
Он равен true
если тип соответствует требованиям IEEE 754-2008. Далее в ответе предполагается, что тип double
удовлетворяет требованиям этого стандарта.
Так вот, если поделить 1.0
на 0.0
, то получится положительная бесконечность (Infinity). Один из возможных способов, которым реализация посредством std::cout
может отобразить бесконечность — это 1.#INF
.
Разность двух бесконечностей с одинаковым знаком — это NaN
. Один из возможных способов, которым реализация посредством std::cout
может отобразить NaN
— это -1.#IND
.
- Переменная
ind
в вашем примере равна NaN
. NaN
не равен ничему, включая самого себя. Вот почему выражение ind != ind
равно true
.
- Конструкцию
if(ind != ind)
можно использовать для проверки на NaN
, но не на бесконечность. Начиная с C++11, в заголовочном файле <cmath>
есть функция std::isnan
для проверки на NaN
и функция std::isinf
для проверки на бесконечность.
- И
NaN
'ы и бесконечности хранятся в памяти также как и все остальные числа с плавающей точкой: бит знака, биты экспоненты и биты мантиссы. Если все биты экспоненты установлены в 1
, а все биты мантиссы установлены в 0
, то это бесконечность (положительная или отрицательная, в зависимости от знакового бита). Если все биты экспоненты установлены в 1
, а среди битов мантиссы есть хотя бы один не нулевой, то это NaN
.
- Операторы
<
, <=
, ==
, >=
, >
возвращают false
в случае, если по крайней мере один из операндов NaN
. Поэтому все выражения ind < 5.4
, ind == 5.4
, ind > 5.4
возвращают false
. Бесконечности же сравниваются обычным образом: −Infinity < every_finite_number < +Infinity
.
Стандарт языка C++ не особо требователен к типам с плавающей точкой. Многие аспекты поведения таких типов определяются реализацией. Например, стандарт IEEE 754-2008 разрешает, чтобы в случае, если один из операндов бинарного >
— NaN
, то генерировалось исключение.
При работе с числами с плавающей точкой, стоит помнить про возможные агрессивные оптимизации, которые компилятор может применить. Например, в Visual Studio, при использовании опции /fp:fast компилятор запросто может выражение pinf - pinf
заменить нулём (что в случае, если pinf
равен бесконечности или NaN
— не верно), а выражение ind != ind
заменить на false
(что в случае, если ind
равен NaN
— не верно).