Что делать 1.#INF00, -1.#IND00 и -1.#Инд имеете в виду?
я возился с некоторым кодом C, используя поплавки, и я получаю 1.#INF00, -1.#IND00 и -1.#IND, когда я пытаюсь распечатать плавает на экране. Что означают эти ценности?
Я считаю, что 1.#INF00 означает положительную бесконечность, но как насчет -1.#IND00 и -1.#IND? Я также видел иногда это значение: 1.$NaN, который не является числом, но что вызывает эти странные значения и как они могут помочь мне с отладкой?
Я использую MinGW который я считаю использует IEEE 754 представление для чисел с плавающей точкой.
может ли кто-нибудь перечислить все эти недопустимые значения и что они означают?
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)