Содержание страницы
28.14. fpectl – Управление исключениями с плавающей точкой¶fpectl – Floating point exception control
Примечание
Модуль fpectl не собирается по умолчанию, и его использование не рекомендуется и может быть опасным, за исключением случаев, когда это делают эксперты. См. также раздел Ограничения и прочие соображения об ограничениях для получения дополнительной информации.
Большинство компьютеров выполняют операции с плавающей запятой в соответствии с так называемым стандартом IEEE-754. На любом реальном компьютере некоторые операции с плавающей запятой дают результаты, которые невозможно выразить в виде обычного числа с плавающей запятой. Например, попробуйте
>>> import math
>>> math.exp(1000)
inf
>>> math.exp(1000) / math.exp(1000)
nan
(Приведённый выше пример будет работать на многих платформах. DEC Alpha может быть исключением.) «Inf» – это специальное нечисловое значение в IEEE-754, обозначающее «бесконечность», а «nan» означает «не число». Обратите внимание, что, помимо нечисловых результатов, ничего особенного не произошло, когда вы попросили Python выполнить эти вычисления. На самом деле это поведение по умолчанию, предписанное стандартом IEEE-754, и если оно вас устраивает, прекратите чтение сейчас.
В некоторых обстоятельствах лучше возбудить исключение и остановить обработку в том месте, где была предпринята ошибочная операция. Модуль fpectl предназначен для таких ситуаций. Он предоставляет управление блоками с плавающей запятой от нескольких производителей оборудования, позволяя пользователю включить генерацию SIGFPE всякий раз, когда происходит любое из исключений IEEE-754: Деление на ноль, Переполнение или Недопустимая операция. В сочетании с парой макросов-обёрток, которые вставляются в C-код, составляющий вашу систему Python, SIGFPE перехватывается и преобразуется в исключение Python FloatingPointError.
Модуль fpectl определяет следующие функции и может возбуждать указанное исключение:
- fpectl.turnon_sigfpe()¶
Включает генерацию SIGFPE и устанавливает соответствующий обработчик сигналов.
- fpectl.turnoff_sigfpe()¶
Сбрасывает обработку исключений с плавающей запятой по умолчанию.
- exception fpectl.FloatingPointError¶
После выполнения turnon_sigfpe() операция с плавающей запятой, которая возбуждает одно из исключений IEEE-754: Деление на ноль, Переполнение или Недопустимая операция, в свою очередь возбудит это стандартное исключение Python.
28.14.1. Пример¶Example
Следующий пример демонстрирует, как запустить и протестировать работу модуля fpectl.
>>> import fpectl
>>> import fpetest
>>> fpectl.turnon_sigfpe()
>>> fpetest.test()
overflow PASS
FloatingPointError: Overflow
div by 0 PASS
FloatingPointError: Division by zero
[ more output from test elided ]
>>> import math
>>> math.exp(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
FloatingPointError: in math_1
28.14.2. Ограничения и другие соображения¶Limitations and other considerations
Настройка данного процессора на перехват ошибок с плавающей запятой IEEE-754 в настоящее время требует специального кода для каждой архитектуры. Возможно, придётся изменить fpectl для управления вашим конкретным оборудованием.
Преобразование исключения IEEE-754 в исключение Python требует, чтобы макросы-обёртки PyFPE_START_PROTECT и PyFPE_END_PROTECT были вставлены в ваш код надлежащим образом. Сам Python был изменён для поддержки модуля fpectl, но многие другие программы, представляющие интерес для численных аналитиков, – нет.
Модуль fpectl не является потокобезопасным.
См. также
Некоторые файлы в дистрибутиве исходного кода могут быть интересны для более подробного изучения того, как работает этот модуль. Заголовочный файл Include/pyfpe.h обсуждает реализацию этого модуля довольно подробно. Modules/fpetestmodule.c содержит несколько примеров использования. Много дополнительных примеров можно найти в Objects/floatobject.c.