Почему при вычислении знака произведения двух переменных используется абсолютное значение?

Модуль библиотеки Netlib для функции поиска корней Brent проверяет, что знаки двух переменных различаются следующим образом:

if (fa * (fb/dabs(fb)) .le. 0.0d0) go to 20
...

Почему эта проверка должна включать /dabs(fb) вместо того, чтобы быть просто (fa*fb) .le. 0.0d0? Я быстро проверил Python, и кажется, что для очень больших значений (+/-1e200) для x и y, где x*y=+/- inf, сравнение x*y<= 0 по-прежнему работает правильно.

1 ответ

Решение

Фортран никогда не указывал такую ​​функцию, как signs_differ(x,y), поэтому обычно это делается лично.

x*y<0x*y.lt.0) не спрашивает то же самое, что "имеют ли x и y разные знаки?". В то время как произведение x и y, являющееся положительным, означает, что x и y имеют один и тот же знак в (математических) действительных числах, это неверно для (вычислительных) чисел с плавающей запятой.

Умножение с плавающей запятой x*yможет переполниться, привести к бесконечному значению со знаком (поднятию флага IEEE), при этом сравнение возвращает ожидаемое логическое значение, но это не всегда верно. Было много систем, не относящихся к IEEE, и системы IEEE могут видеть, что этот флаг поднимается и прерывается (или имеют какое-то дорогостоящее отвлечение обработки). Это совсем не то же самое, что "имеют ли x и y один и тот же знак?".

x*(y/dabs(y)) не переполняется, является портативным и потенциально дешевле, чем (x/dabs(x))*(y/dabs(y)) - игнорирование проблем, связанных с dabs() и подписанные нули.

Современный Фортран имеет такие функции, как sign, ieee_copy_sign и ieee_signbit которого не было 40 лет назад.

Другие вопросы по тегам