Что означают 1. # INF00, -1. # IND00 и -1. # IND? - PullRequest
61 голосов
/ 07 декабря 2008

Я возлюсь с кодом C, используя поплавки, и получаю 1. # INF00, -1. # IND00 и -1. # IND, когда пытаюсь напечатать поплавки на экране. Что означают эти значения?

Я считаю, что 1. # INF00 означает положительную бесконечность, но как насчет -1. # IND00 и -1. # IND? Я также иногда видел это значение: 1. $ NaN, который не является числом, но что вызывает эти странные значения и как они могут помочь мне в отладке?

Я использую MinGW , который, я полагаю, использует IEEE 754 представление для чисел с плавающей точкой.

Может ли кто-нибудь перечислить все эти недопустимые значения и что они значат?

Ответы [ 4 ]

65 голосов
/ 07 декабря 2008

С Исключения IEEE с плавающей точкой в ​​C ++ :

Эта страница ответит на следующие вопросы.

  • Моя программа только что распечатала 1. # IND или 1. # INF (в Windows) или nan или inf (в Linux). Что случилось?
  • Как я могу определить, является ли число действительно числом, а не NaN или бесконечностью?
  • Как я могу узнать больше деталей во время выполнения о видах NaN и бесконечностях?
  • У вас есть пример кода, чтобы показать, как это работает?
  • Где я могу узнать больше?

Эти вопросы касаются исключений с плавающей запятой. Если вы получаете какой-то странный нечисловой вывод, где ожидаете число, вы либо превысили конечные пределы арифметики с плавающей запятой, либо запросили какой-то неопределенный результат. Для простоты я остановлюсь на работе с двойным типом с плавающей точкой. Аналогичные замечания справедливы для типов с плавающей точкой.

Отладка 1. # IND, 1. # INF, nan и inf

Если ваша операция сгенерирует большее положительное число, чем может быть сохранено в double, операция вернет 1. # INF в Windows или inf в Linux. Точно так же ваш код вернет -1. # INF или -inf, если результатом будет отрицательное число, слишком большое, чтобы его можно было хранить в двойном размере. Деление положительного числа на ноль дает положительную бесконечность, а деление отрицательного числа на ноль - отрицательную бесконечность. Пример кода в конце этой страницы продемонстрирует некоторые операции, создающие бесконечность.

Некоторые операции не имеют математического смысла, например, получение квадратного корня из отрицательного числа. (Да, эта операция имеет смысл в контексте комплексных чисел, но двойное представляет действительное число, и поэтому нет двойного для представления результата.) То же самое верно для логарифмов отрицательных чисел. И sqrt (-1.0), и log (-1.0) будут возвращать NaN, общий термин для «числа», то есть «не числа». Windows отображает NaN как -1. # IND («IND» для «неопределенного»), в то время как Linux отображает Nan. Другие операции, которые возвращали бы NaN, включают 0/0, 0 * ∞ и ∞ / ∞. Смотрите пример кода ниже для примеров.

Короче говоря, если вы получаете 1. # INF или inf, ищите переполнение или деление на ноль. Если вы получаете 1. # IND или nan, ищите нелегальные операции. Может быть, у вас просто есть ошибка. Если он более тонкий, и у вас есть что-то, что трудно вычислить, см. Избежание переполнения, недопущения и потери точности. В этой статье даны приемы для вычисления результатов, которые имеют промежуточное переполнение при непосредственном вычислении.

3 голосов
/ 10 августа 2012

Для тех из вас, в среде .NET следующее может быть удобным способом отфильтровать нечисловые числа (этот пример в VB.NET, но он, вероятно, похож на C #):

If Double.IsNaN(MyVariableName) Then
    MyVariableName = 0 ' Or whatever you want to do here to "correct" the situation
End If

Если вы попытаетесь использовать переменную со значением NaN, вы получите следующую ошибку:

Значение было либо слишком большим, либо слишком маленьким для десятичной дроби.

2 голосов
/ 25 сентября 2018

Для всех, кто интересуется разницей между -1.#IND00 и -1.#IND (которую конкретно задал вопрос, и ни один из ответов не адресован):

-1.#IND00

Это, в частности, означает ненулевое число, деленное на ноль, например, 3.14 / 0 ( источник )

-1.#IND (синоним NaN)

Это означает одну из четырех вещей (см. wiki из source ):

1) sqrt или log отрицательного числа

2) операции, в которых обе переменные равны 0 или бесконечности, например, 0 / 0

3) операции, в которых хотя бы одна переменная уже равна NaN, например, NaN * 5

4) триггер вне диапазона, например, arcsin(2)

2 голосов
/ 11 июля 2016

На ваш вопрос "кто они" уже ответили выше.

Что касается отладки (ваш второй вопрос) и разработки библиотек, в которых вы хотите проверить специальные входные значения, в Windows C ++ могут оказаться полезными следующие функции:

_isnan (), _isfinite () и _fpclass ()

В Linux / Unix вы должны найти полезными isnan (), isfinite (), isnormal (), isinf (), fpclassify () (и вам может потребоваться связать с libm, используя флаг компилятора -lm).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...