Цель if ((huge + x) > one) return x;
- создать неточное исключение с плавающей точкой и затем вернуться из процедуры.
Исключение с плавающей точкой не является ловушкой или обработчиком.Это просто означает, что в операции с плавающей точкой произошло нечто необычное.Что происходит потом, зависит от обстоятельств операции.В частности, среда с плавающей запятой может быть установлена таким образом, чтобы неточное исключение просто поднимало флаг в специальном регистре и продолжало операцию, предоставляя числовой результат.Или это может быть установлено так, что неточное исключение вызывает прерывание, и управление программой перенаправляется обработчику прерываний.
Этот код, реализующий atan
, не знает, как устанавливается среда с плавающей запятой.Может быть, он может получить настройки, но не хочет беспокоиться об этом.Учитывая, что она решила, что функция арктангенса не может быть точно вычислена, самый простой способ вызвать неточное исключение с плавающей запятой - просто выполнить простое сложение, которое дает неточный результат.Это неточное сложение будет иметь то же поведение, которое желательно для неточного арктангенса - оно будет либо просто поднимать флаг, либо вызывать ловушку, в зависимости от настроек.
Что касается сравнения с ix < 0x3e200000
,это не ясно.С одной стороны, ix
был откорректирован для отражения абсолютного значения, тогда как x
- нет, так почему бы не использовать уже подготовленный ix
вместо использования другой операции для получения fabs(x)
?Кроме того, целочисленное сравнение обычно требует меньше ресурсов процессора, чем сравнение с плавающей запятой, особенно в процессорах того времени, когда был написан этот код.Или, может быть, автор просто использовал один над автором, возможно, написав большую часть своего кода, используя ix
для работы с кодировкой с плавающей точкой, а не x
для работы со значением с плавающей точкой, и они сделалине хочу переключаться туда-сюда без необходимости.Это также может быть связано с тем, что код был написан до того, как стала доступна шестнадцатеричная запись с плавающей запятой (поэтому мы могли написать x < 0x1p-29f
), а компиляторы не были хороши в преобразовании десятичных чисел в значения с плавающей запятой, поэтому они не хотели писатьиз значения с плавающей запятой в исходном коде.
Этот вид кода проблематичен и сильно зависит от реализации C, для которой он написан.Как правило, компилятор не может гарантировать, что (huge + x) > one
будет оцениваться во время выполнения программы.Компилятор может оценить его во время компиляции.Предположительно, хотя, если этот код написан для конкретной реализации C, они знают, что компилятор или оценит его во время компиляции, или обеспечит достижение того же результата, включая повышение неточного исключения с плавающей точкой.
На первый взгляд, (huge + x) > one
, похоже, не делает ничего полезного, чего не делает только huge + x
, но, возможно, автор знал что-то о компиляторе, чего нет у нас.
huge
делаетне должно быть 1.0e300
.Любое значение, настолько большое, что сумма huge
и x
не может быть точной, будет достаточным.