Что делать 1.#INF00, -1.#IND00 и -1.#Инд имеете в виду?


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

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

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

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

4 60

4 ответа:

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

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

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

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

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

Если ваша операция будет генерировать большее положительное число, чем может быть сохранено в двойнике, операция вернет 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, ищите незаконные операции. Может быть, у вас просто есть ошибка. Если это более тонко, и у вас есть что-то, что трудно вычислить, см. Во избежание переполнения, переполнение и потерю точности. Эта статья дает приемы для вычисления результатов, которые имеют промежуточные шаги переполнения, если вычисляется непосредственно.

для тех из вас, кто находится в среде .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, вы получите следующую ошибку:

значение было либо слишком большим, либо слишком маленьким для десятичного числа.

на ваш вопрос "что это такое" уже дан ответ выше.

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

_isnan(), _isfinite(), и _fpclass()

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

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

-1.#IND00

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

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

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

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

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

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

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