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