fortran - 为什么计算两个变量乘积的符号要用绝对值?

标签 fortran netlib

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 在(数学)实数中符号相同,但对于(计算的) float 而言并非如此。

浮点乘法 x*y可能溢出,导致带符号的无限值(引发 IEEE 标志),比较返回预期的逻辑值,但这并不总是正确的。有许多非 IEEE 系统和 IEEE 系统可能会看到该标志被升起并中止(或者有一些昂贵的处理转移)。这与“x 和 y 的符号相同吗?”完全不同。

x*(y/dabs(y))不会溢出,“便携”并且可能比 (x/dabs(x))*(y/dabs(y)) 便宜- 忽略围绕 dabs() 的问题和有符号的零。

现代 Fortran 语言有 sign 等函数, ieee_copy_signieee_signbit这在 40 年前是不存在的。

关于fortran - 为什么计算两个变量乘积的符号要用绝对值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64706034/

相关文章:

c++ - 如何从 C++ 调用 fortran 例程?

visual-studio-code - 如何在VSCODE中设置tasks.json文件来编译Fortran程序?

fortran - 一种在 Fortran 中抑制 "unused dummy argument"警告的便携方法

Fortran 在函数中增加动态数组大小

Fortran 隐式更改类型

fortran - Fortran 2003 中测试 null 参数

apache-spark - 如何为 Spark 2.2.0 正确设置 native ARPACK

apache-spark - Spark netlib-java BLAS