in commons-math-core/src/main/java/org/apache/commons/math4/core/jdkmath/AccurateMath.java [2640:2726]
public static double atan2(double y, double x) {
if (Double.isNaN(x) || Double.isNaN(y)) {
return Double.NaN;
}
if (y == 0) {
final double invx = 1d / x;
if (invx == 0) { // X is infinite
if (x > 0) {
return y; // return +/- 0.0
}
return copySign(Math.PI, y);
}
if (x < 0 || invx < 0) {
return copySign(Math.PI, y);
}
return x * y;
}
// y cannot now be zero
if (y == Double.POSITIVE_INFINITY) {
if (x == Double.POSITIVE_INFINITY) {
return Math.PI * F_1_4;
}
if (x == Double.NEGATIVE_INFINITY) {
return Math.PI * F_3_4;
}
return Math.PI * F_1_2;
}
if (y == Double.NEGATIVE_INFINITY) {
if (x == Double.POSITIVE_INFINITY) {
return -Math.PI * F_1_4;
}
if (x == Double.NEGATIVE_INFINITY) {
return -Math.PI * F_3_4;
}
return -Math.PI * F_1_2;
}
if (x == Double.POSITIVE_INFINITY) {
return y > 0 ? 0d : -0d;
}
if (x == Double.NEGATIVE_INFINITY) {
return y > 0 ? Math.PI : -Math.PI;
}
// Neither y nor x can be infinite or NAN here
if (x == 0) {
return y > 0 ? Math.PI * F_1_2 : -Math.PI * F_1_2;
}
// Compute ratio r = y/x
final double r = y / x;
if (Double.isInfinite(r)) { // bypass calculations that can create NaN
return atan(r, 0, x < 0);
}
double ra = doubleHighPart(r);
double rb = r - ra;
// Split x
final double xa = doubleHighPart(x);
final double xb = x - xa;
rb += (y - ra * xa - ra * xb - rb * xa - rb * xb) / x;
final double temp = ra + rb;
rb = -(temp - ra - rb);
ra = temp;
if (ra == 0) { // Fix up the sign so atan works correctly
ra = copySign(0d, y);
}
// Call atan
return atan(ra, rb, x < 0);
}