此代码
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编译器的负面支持?
答案 0 :(得分:4)
Fortran 2008(13.7.159)将参数sqrt
的{{1}}函数的结果定义为(我强调):
结果的值等于与处理器有关的X的平方根近似值。类型complex的结果是主体部分的实数值大于或等于零的主值。 当结果的实部为零时,虚部与X的虚部具有相同的符号。
您的平方根确实确实有零个实部,因此让我们看一下论证的虚部的符号。 X
的虚部的符号是什么?如果您的处理器支持带符号的零,则可能为负。在这种情况下,结果的虚部应根据标准的要求为负。
在所有其他情况下,没有理由期望参数的虚部为负,而不是正零。