Hi! Richard B. Kreckel wrote:
Of course I can't oversee the consequences of a change, it would be convenient to code decisions based on the argument in a uniform way though.
Let's see. atan2 appears in LIA-2 and LIA-3, though not in LIA-1. It isn't defined directly, but one finds for instance the formula in LIA-3: ln(z)=ln(|z|)+I*atan2(y,x) for z=x+I*y. This implies to bring the branch cut in alignment with the branch cut of ln(x+I*y). The latter is defined as continuous with the second quadrant of the x-y plane (c.f. C99, 7.3.3.2: "[...] implementations shall map a cut so the function is continuous as the cut is approached coming around the finite endpoint of the cut in a counter clockwise direction. (Brnach cuts for the functions specified here have just one finite endpoint.)" As I said, this branch cut specification for ln(z) is consistent with the other standards.
IINM this implies that atan2(0,-4) should be +Pi, not -Pi.
The old definition of atan2(0,-4)==-Pi did not only disagree with C99, it also caused real inconsistencies: ex z = -4; cout << log(z) << endl; // log(4)+I*Pi cout << log(z).imag_part() << endl; // -Pi I've fixed that on both active branches in CVS.
Unless somebody is going to hold me back I'm going to fix this in GiNaC RSN. I'll also consider some minor other issues like atan2(I*1.1,1.1) throws an exception but atan2(I,1)->atan2(I,1) (both arguments of atan2 must be real, full stop.)
Restricting atan2(y,x) to real arguments would be more restrictive than is needed. A suitable analytic continuation of atan2(y,x) to complex arguments y and x can be found in some other systems, too: -I*log((x+I*y)/sqrt(x^2+y^2)). As a result, more values are accepted, now. Cheers -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>