6

This code

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

gives me this output

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

I believe that the correct algebra is sqrt(-1)=i. Why the result of the last line?

The compiler version is GCC 7.3.0, running on Linux openSUSE 42.2 (x86_64).

EDIT

Following @francescalus answer I have tried more cases:

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

and I get

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

So, it seems that my compiler support negative zeros for real numbers. So, I guess it is important to care when working with variables like this:

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

Here I get again the wrong result, but the zero negative thing is more difficult to predict. I have so many questions! Do you know some other exmple that can induce a mistake? Do you have an advice to avoid this mistakes? Do you now some compiler flag to turn off the negative cero support for the GCC compiler?

alexis
  • 410
  • 4
  • 18
  • Please specify your compiler, compiler version and OS. – albert Oct 31 '18 at 15:04
  • The compiler version is GCC 7.3.0, running on Linux openSUSE 42.2 (x86_64). I just edit the question to include it. – alexis Oct 31 '18 at 15:06
  • Same thing happens with GCC 4.8.5 – alexis Oct 31 '18 at 15:08
  • 1
    Be aware that both results are mathematically correct. `i*i = -1` and `(-i)*(-i) = -1` – kvantour Nov 01 '18 at 17:50
  • Yes! I am just reading about that. From wikipedia: "the sign of the imaginary part of the root is taken to be the same as the sign of the imaginary part of the original number, or positive when zero", so with this definition the correct result should still be `i`. The existence of a negative zero trigger the mistake. – alexis Nov 02 '18 at 15:02

1 Answers1

5

Fortran 2008 (13.7.159) defines the result of the sqrt function, for argument X, as (my emphasis):

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.

Your square roots do indeed have zero real part, so let's look at the sign of the imaginary part of your argument. What is the sign of the imaginary component of -(1,0)? If your processor supports signed zero, then it could well be negative. In which case, the imaginary part of the result should be negative according to the standard's requirement.

In all other cases, there'd be no reason to expect the imaginary component of the argument to be negative, rather than positive, zero.

francescalus
  • 30,576
  • 16
  • 61
  • 96
  • Wow! So, if I am working with a complex variable (say `a`) and in some operation the real part of (`a`) become cero, I must check the sign of that cero to avoid get a completely different result? – alexis Oct 31 '18 at 15:35
  • Thank you, I edited the question and include more questions, but I just get in your answer the solution I was looking for. – alexis Oct 31 '18 at 16:44