为什么计算两个变量乘积的符号要用绝对值?
Why does calculation of sign of product of two variables use absolute value?
Brent root-finding function 的 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 仍然可以正常工作.
Fortran从来没有指定过signs_differ(x,y)
这样的函数,所以一般都是自己实现这样的东西
x*y<0
(和 x*y.lt.0
)与“x 和 y 的符号不同吗?”问的不是同一件事。虽然 x 和 y 的乘积为正意味着 x 和 y 在(数学)实数中是相同的符号,但对于(计算的)浮点数而言并非如此。
浮点乘法 x*y
可能溢出,导致带符号的无限值(引发 IEEE 标志),比较返回预期的逻辑值,但这并不总是正确的。有许多 non-IEEE 系统,IEEE 系统可能会看到该标志被升起并中止(或者有一些昂贵的处理转移)。这与“x 和 y 的符号相同吗?”完全不同。
x*(y/dabs(y))
不会溢出,是“便携的”并且可能比 (x/dabs(x))*(y/dabs(y))
便宜 - 忽略围绕 dabs()
和符号零的问题。
现代 Fortran 具有 40 年前不存在的 sign
、ieee_copy_sign
和 ieee_signbit
等函数。
Brent root-finding function 的 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 仍然可以正常工作.
Fortran从来没有指定过signs_differ(x,y)
这样的函数,所以一般都是自己实现这样的东西
x*y<0
(和 x*y.lt.0
)与“x 和 y 的符号不同吗?”问的不是同一件事。虽然 x 和 y 的乘积为正意味着 x 和 y 在(数学)实数中是相同的符号,但对于(计算的)浮点数而言并非如此。
浮点乘法 x*y
可能溢出,导致带符号的无限值(引发 IEEE 标志),比较返回预期的逻辑值,但这并不总是正确的。有许多 non-IEEE 系统,IEEE 系统可能会看到该标志被升起并中止(或者有一些昂贵的处理转移)。这与“x 和 y 的符号相同吗?”完全不同。
x*(y/dabs(y))
不会溢出,是“便携的”并且可能比 (x/dabs(x))*(y/dabs(y))
便宜 - 忽略围绕 dabs()
和符号零的问题。
现代 Fortran 具有 40 年前不存在的 sign
、ieee_copy_sign
和 ieee_signbit
等函数。