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

Fortran sqrt of complex number -1 gives different results

这个代码

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,运行 on 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 编译器的负面 cero 支持吗?

Fortran 2008 (13.7.159) 定义了 sqrt 函数的结果,对于参数 X,如(我强调的):

The result has a value equal to a processor-dependent approximation to the square root of X. A result of type complex is the principal value with the real part greater than or equal to zero. When the real part of the result is zero, the imaginary part has the same sign as the imaginary part of X.

你的平方根实部确实为零,所以让我们看看你的论证虚部的符号。 -(1,0)的虚部符号是什么?如果您的处理器支持带符号的零,那么它很可能是负数。在这种情况下,根据标准的要求,结果的虚部应该是负数。

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