复数为-1的Fortran sqrt给出不同的结果

时间:2018-10-31 15:01:50

标签: fortran complex-numbers

此代码

print *, sqrt(cmplx(-1))
print *, sqrt(cmplx(-1,0))
print *, sqrt((-1,0))
print *, sqrt(-(1,0))

给我这个输出

(0.00000000,1.00000000)
(0.00000000,1.00000000)
(0.00000000,1.00000000)
(0.00000000,-1.00000000)

我相信正确的代数是sqrt(-1)=i。为什么最后一行结果呢?

编译器版本为GCC 7.3.0,可在Linux openSUSE 42.2(x86_64)上运行。

编辑

在@francescalus回答之后,我尝试了更多案例:

print *, sqrt((-1,-0))
print *, sqrt((-1,-0.))
print *, (-1,-0)
print *, (-1,-0.)

我明白了

(0.00000000,1.00000000)
(0.00000000,-1.00000000)
(-1.00000000,0.00000000)
(-1.00000000,-0.00000000)

因此,看来我的编译器支持real数字为负零。因此,我想在使用这样的变量时要特别小心:

complex             :: asd 
asd=(1.,0.)
print *, sqrt(-asd)

在这里,我再次得到错误的结果,但是零负数则更难以预测。我有很多问题!您是否知道其他一些可能导致错误的示例?您有建议要避免这种错误?您现在是否有一些编译器标记来关闭对GCC编译器的负面支持?

1 个答案:

答案 0 :(得分:4)

Fortran 2008(13.7.159)将参数sqrt的{​​{1}}函数的结果定义为(我强调):

  

结果的值等于与处理器有关的X的平方根近似值。类型complex的结果是主体部分的实数值大于或等于零的主值。 当结果的实部为零时,虚部与X的虚部具有相同的符号。

您的平方根确实确实有零个实部,因此让我们看一下论证的虚部的符号。 X的虚部的符号是什么?如果您的处理器支持带符号的零,则可能为负。在这种情况下,结果的虚部应根据标准的要求为负。

在所有其他情况下,没有理由期望参数的虚部为负,而不是正零。