首页 > 解决方案 > 为什么计算两个变量的乘积符号使用绝对值?

问题描述

Brent 寻根函数的 Netlib 库模块检查两个变量的符号是否不同,如下所示:

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

为什么这个检查包括/dabs(fb)而不是简单的(fa*fb) .le. 0.0d0?我用 Python 做了一个快速检查,似乎 x 和 y 的值非常大 (+/-1e200),其中 x*y=+/- inf,比较 x*y<= 0 仍然可以正常工作。

标签: fortrannetlib

解决方案


Fortran 从未指定过类似的函数signs_differ(x,y),因此通常会亲自实现这样的事情。

x*y<0(and x*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()和签名零的问题更便宜。

现代 Fortran 具有 , 等功能,sign这些功能在 40 年前并不存在。ieee_copy_signieee_signbit


推荐阅读