## digitalmars.D.learn - std.math.atan2 -- range of output

- Joseph Rushton Wakeling (27/27) Nov 30 2013 I've run into an interesting little issue with respect to std.math.atan2...

I've run into an interesting little issue with respect to std.math.atan2. This is used to calculate the "argument" of complex numbers, that is, the angle in polar coordinates. atan2(y, x) gives the argument of the complex number x + iy. Now, theoretically, atan2 ought to return a value in the range (-PI, PI] or [0, 2 * PI) in order to avoid potential ambiguities in output: an argument of PI or -PI is equivalent, and so is one of 0 and 2 * PI. However, it's possible to get it to return a value of -PI as follows: writeln(atan2(0.0, -1.0)); // argument of -1 : it's PI. writeln(atan2(-0.0, -1.0)); // still arg of -1, but this time it's -PI. This can be traced to L863-869 of std/math.d where we have the lines: if (y == 0.0) { if (x >= 0 && !signbit(x)) return copysign(0, y); else return copysign(PI, y); } That is to say, y's sign is copied to the returned argument value, so if we provide y as -0.0 instead of 0.0, we get -PI instead of PI. Can someone explain the logic here? The effect so far as I can see is to render an unpleasant ambiguity for dependent functions like std.complex.arg where it's possible for the user to wind up with an out-of-the-blue -PI argument where PI was expected. I ask because I ran into this while trying to create a unittest for the case (-1.0) ^^ complex(1.0, 1.0); ... as part of the work I'm doing on https://d.puremagic.com/issues/show_bug.cgi?id=11652

Nov 30 2013