【问题标题】:Why does calculation of sign of product of two variables use absolute value?为什么计算两个变量的乘积符号使用绝对值?
【发布时间】:2021-02-18 16:19:41
【问题描述】:

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

【问题讨论】:

  • 问:如果您只对符号感兴趣...那么(fb/dabs(fb)) ("+1/-1") 没有任何“错误”。我猜它只是减轻了溢出的风险?出于历史原因?
  • @paulsm4 看来您在减轻溢出风险方面可能是对的。 This (old) page 描述了浮点溢出的默认 Fortran 行为(对于 f77 和 f90 不同)和捕获异常。我猜 gcc 会有类似的选择。

标签: fortran netlib


【解决方案1】:

Fortran 从来没有指定像signs_differ(x,y) 这样的函数,所以一般都是个人实现这样的东西。

x*y<0(和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 具有 signieee_copy_signieee_signbit 等 40 年前不存在的功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多