Fortran中的负指数导致NaN

4
非常基础的Fortran问题。以下函数返回NaN,但我似乎无法弄清楚原因:
```F_diameter = 1. - (2.71828**(-1.0*((-1. / 30.)**1.4)))```
我已经输入了2.71...而不是使用```exp()```,但它们都以同样的方式失败。 我注意到当小数部分(-1/30)为负数时,才会得到NaN。正数可以正常计算。
谢谢!

1
问题似乎出在-1/30 ** 1.4上;显然gfortran无法将负数提高到分数幂。不确定原因。 - micah
ire_and_curses 给出了一个很好的答案。请注意,这应该是所有Fortran编译器的标准行为 - 因为Fortran是静态类型的,当对REAL进行操作时,它不能变成COMPLEX - 而是会引发异常。 - milancurcic
2个回答

10
问题在于你在对一个负数开根,这会得到一个复数的答案。如果你想象一下比如...。
The problem is that you are taking a root of a negative number, which would give you a complex answer. This is more obvious if you imagine e.g.
(-1) ** (3/2)

等同于

(1/sqrt(-1))**3

换句话说,你的分数指数不能轻易地作用于负数。


0

这里有另一个今天我学到并想要补充给ire_and_curses的答案中的有趣点:Fortran编译器似乎使用连续的乘法计算整数的幂。例如

      PROGRAM Test
      PRINT *, (-23) ** 6
      END PROGRAM

正常工作并返回 148035889 作为答案。

但对于实数指数,编译器使用对数函数:y**x = 10**(x * log(y))(也许现代编译器做法不同,但我的书是这样说的)。由于负对数会导致复杂结果,因此这个方法不可用:

      PROGRAM Test
      PRINT *, (-23) ** 6.1
      END PROGRAM

甚至会给出编译器错误:

Error: Raising a negative REAL at (1) to a REAL power is prohibited

从数学角度来看,这个问题似乎也非常有趣:https://math.stackexchange.com/questions/1211/non-integer-powers-of-negative-numbers

1
这源于Fortran标准中明确的禁止规定,就像引用的错误信息所示。它与实现实际上没有关系。 (-23)**6.0 也是不被允许的。实际上,整数指数是相当特殊的。 - francescalus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接