Документация Python неофициальный перевод
Содержание страницы

28.16. 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.16.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 <module>
FloatingPointError: in math_1

28.16.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.