Float или Double Special Value
-
22-07-2019 - |
Вопрос
У меня есть двойные (или плавающие) переменные, которые могут быть " empty " ;, так как в них нет действительного значения. Как я могу представить это условие с помощью встроенных типов float и double?
Одним из вариантов может быть оболочка с плавающей точкой и логическим значением, но она не может & # 180; t работать, поскольку в моих библиотеках есть контейнеры, в которых хранятся двойники, а не объекты, которые ведут себя как двойники. Другой будет использовать NaN (std :: numeric_limits). Но я не вижу способа проверить, является ли переменная NaN.
Как я могу решить проблему необходимости " специального " значение с плавающей запятой, чтобы означать что-то кроме числа?
Решение
В Visual C ++ есть нестандартный _isnan(double)
функция, которую вы можете импортировать через float.h
.
В C есть isnan(double)
. что вы можете импортировать через math.h
.
В C ++ есть функция isnan (double), которую вы можете импортировать через cmath
.
Как уже отмечали другие, использование NaN может быть очень хлопотным. Это особый случай, который должен рассматриваться как нулевые указатели. Разница в том, что NaN обычно не вызывает дампы ядра и сбои приложений, но их чрезвычайно сложно отследить. Если вы решили использовать NaN, используйте их как можно меньше. Чрезмерное использование NaN - это оскорбительная практика кодирования.
Другие советы
Мы сделали это с помощью NaN:
double d = std::numeric_limits<double>::signaling_NaN();
bool isNaN = (d != d);
Значения NaN по сравнению на равенство с самим собой приведут к ложному. Таким способом вы проверяете NaN, но, похоже, он действителен только в том случае, если std::numeric_limits<double>::is_iec559
имеет значение true (если это так, он также соответствует ieee754). Р>
В C99 есть макрос isnan
для этого в math.h
, который также проверяет число с плавающей запятой на значение NaN.
Это не встроенный тип, но я обычно использую boost::optional
для такого рода вещей. Если вы абсолютно не можете это использовать, возможно, указатель сработает - если указатель равен NULL, то вы знаете, что результат не содержит допустимого значения.
Одним из вариантов может быть оболочка с плавающей точкой и логическим значением, но это не может & # 180; t работать, поскольку в моих библиотеках есть контейнеры, в которых хранятся значения типа double, а не объекты, которые ведут себя как значения типа double .
Это позор. В C ++ легко создать шаблонный класс, который автоматически преобразуется в фактический двойной (ссылочный) атрибут. (Или ссылка на любой другой тип по этому вопросу.) Вы просто используете оператор приведения в шаблонном классе. Например: оператор TYPE & Amp; () {возвращаемое значение; } Затем вы можете использовать HasValue & Lt; double & Gt; везде, где вы обычно используете double.
Другой будет использовать NaN (std :: numeric_limits). Но я не вижу способа проверить, является ли переменная NaN.
Как отметили litb и Джеймс Шек , C99 предоставляет нам isnan ().
Но будь осторожен с этим! Значения Nan делают математику & Amp; логика реально интересная! Можно подумать, что число не может быть одновременно NOT & Gt; = foo и NOT & Lt; = foo. Но с NaN это возможно.
Есть причина, по которой я держу макрос WARN-IF-NAN (X) в своем наборе инструментов. У меня были некоторые интересные проблемы, возникающие в прошлом.