Аппаратное обеспечение IBM PC© Александр Фролов, Григорий ФроловТом 2, книга 1, М.: Диалог-МИФИ, 1992. 12.6. Обработка особых случаевВ арифметическом сопроцессоре имеются два механизма обработки ошибок, возникающих при выполнении различных команд. Первый механизм основан на генерации так называемого прерывания особого случая (INT 10h). Это прерывание вырабатывается в том случае, когда происходит какая-нибудь ошибка (например, деление на нуль) при условии, что соответствующие биты масок особых случаев в регистре управления не установлены. При втором способе обработки ошибок все особые случаи маскируются (соответствующие биты управляющего регистра устанавливаются в единицу) и в случае ошибки сопроцессор в качестве результата возвращает некоторое заранее известное особое значение (нечисло, неопределенность или бесконечность). Программист может выбирать между этими способами обработки ошибок, маскируя или разрешая прерывание по особому случаю. Если прерывание особого случая замаскировано, можно предложить следующий способ обнаружения ошибки:
Кроме того, после выполнения команды полезно проверить получившийся результат на принадлежность к множеству особых значений. Рассмотрим возможные особые случаи сопроцессора в реальном режиме. 12.6.1. Неточный результатВ результате выполнения некоторых операций может возникнуть такая ситуация, когда невозможно точно представить результат. Например, при результатом деления числа 1.0 на 3.0 является бесконечная периодическая двоичная дробь 0.010101... Такое число не может быть представлено точно ни в одном формате вещественных чисел. Обычно неточный результат является результатом округления и может не рассматриваться как ошибка. 12.6.2. ПереполнениеЕсли результат выполнения операции слишком велик и не может быть представлен в формате приемника результата, фиксируется особый случай переполнения. Этот особый случай обязательно произойдет, например, при сложении максимального числа расширенной точности самим с собой или при преобразовании этого числа в формат с двойной или одинарной точностью. Так как для хранения промежуточных результатов используется 80-битовое представление, при выполнении операций над числами с одинарной или двойной точностью переполнения, как правило, не происходит. Огромный диапазон чисел с расширенной точностью гарантирует правильность представления больших по абсолютной величине результатов операций с числами одинарной и двойной точности. 12.6.3. АнтипереполнениеАнтипереполнение возникает тогда, когда результат слишком мал для его представления в формате приемника результата операции, но все же отличен от нуля. Например, если делается попытка преобразовать наименьшее положительное число с расширенной точностью в формат числа с двойной или одинарной точностью. Если вы используете числа только с двойной или одинарной точностью, а для хранения промежуточных результатов используете формат с расширенной точностью, особый случай антипереполнения, как правило, не возникает. 12.6.4. Деление на нульЭтот особый случай возникает при попытке выполнить деление конечного ненулевого числа на нуль. В афинном режиме при делении конечных (положительных или отрицательных) чисел на нуль (положительный или отрицательный) в качестве результата возвращается бесконечность. Знак этой бесконечности зависит от знака делимого и от знака нуля. Например, при делении положительного ненулевого числа на положительный нуль получается положительная бесконечность, при делении положительного ненулевого числа на отрицательный нуль - отрицательная бесконечность. В проективном режиме, а также при попытке деления нуля на нуль возникает особый случай недействительной операции, который будет рассмотрен ниже. 12.6.5. Недействительная операцияЭтот особый случай возникает при попытке выполнения таких запрещенных команд, как деление нуля на нуль, извлечения корня из отрицательного числа, обращение к несуществующему регистру сопроцессора или при попытке использования в качестве операндов команд нечисел, неопределенностей или бесконечности (для трансцендентных функций). 12.6.6. Денормализованный операндМы уже говорили о том, что сопроцессор использует операнды в нормализованной форме. Однако при выполнении операции может оказаться, что результат слишком мал по абсолютной величине для представления его в нормализованной форме. Можно было бы считать такой результат нулевым, однако это привело бы к снижению точности вычислений или даже к грубым ошибкам. Например, вычисляется следующее выражение: (y-x)+x; Если разность (y-x) вызывает антипереполнение и в качестве результата берется нулевое значение, то после вычисления всего выражения получится x. Если же пойти на расширение диапазона представления чисел за счет снижения точности и сформировать результат вычисления разности (y-x) как денормализованное число, выражение будет вычислено правильно и в результате получится y. Таким образом, иногда целесообразно
замаскировать особый случай денормализованного
операнда и использовать денормализованные
числа. Однако при попытке деления на
ненормализованное число или извлечения из него
квадратного корня фиксируется особый случай
недействительной операции. |