125c28e83SPiotr Jasiukajtis /*
225c28e83SPiotr Jasiukajtis * CDDL HEADER START
325c28e83SPiotr Jasiukajtis *
425c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the
525c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License").
625c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License.
725c28e83SPiotr Jasiukajtis *
825c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
925c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing.
1025c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions
1125c28e83SPiotr Jasiukajtis * and limitations under the License.
1225c28e83SPiotr Jasiukajtis *
1325c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each
1425c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1525c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the
1625c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying
1725c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner]
1825c28e83SPiotr Jasiukajtis *
1925c28e83SPiotr Jasiukajtis * CDDL HEADER END
2025c28e83SPiotr Jasiukajtis */
2125c28e83SPiotr Jasiukajtis
2225c28e83SPiotr Jasiukajtis /*
2325c28e83SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
2425c28e83SPiotr Jasiukajtis */
2525c28e83SPiotr Jasiukajtis /*
2625c28e83SPiotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
2725c28e83SPiotr Jasiukajtis * Use is subject to license terms.
2825c28e83SPiotr Jasiukajtis */
2925c28e83SPiotr Jasiukajtis
3025c28e83SPiotr Jasiukajtis /*
3125c28e83SPiotr Jasiukajtis * atan2l(y,x)
3225c28e83SPiotr Jasiukajtis *
3325c28e83SPiotr Jasiukajtis * Method :
3425c28e83SPiotr Jasiukajtis * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
3525c28e83SPiotr Jasiukajtis * 2. Reduce x to positive by (if x and y are unexceptional):
3625c28e83SPiotr Jasiukajtis * ARG (x+iy) = arctan(y/x) ... if x > 0,
3725c28e83SPiotr Jasiukajtis * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
3825c28e83SPiotr Jasiukajtis *
3925c28e83SPiotr Jasiukajtis * Special cases:
4025c28e83SPiotr Jasiukajtis *
4125c28e83SPiotr Jasiukajtis * ATAN2((anything), NaN ) is NaN;
4225c28e83SPiotr Jasiukajtis * ATAN2(NAN , (anything) ) is NaN;
4325c28e83SPiotr Jasiukajtis * ATAN2(+-0, +(anything but NaN)) is +-0 ;
4425c28e83SPiotr Jasiukajtis * ATAN2(+-0, -(anything but NaN)) is +-PI ;
4525c28e83SPiotr Jasiukajtis * ATAN2(+-(anything but 0 and NaN), 0) is +-PI/2;
4625c28e83SPiotr Jasiukajtis * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
4725c28e83SPiotr Jasiukajtis * ATAN2(+-(anything but INF and NaN), -INF) is +-PI;
4825c28e83SPiotr Jasiukajtis * ATAN2(+-INF,+INF ) is +-PI/4 ;
4925c28e83SPiotr Jasiukajtis * ATAN2(+-INF,-INF ) is +-3PI/4;
5025c28e83SPiotr Jasiukajtis * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-PI/2;
5125c28e83SPiotr Jasiukajtis *
5225c28e83SPiotr Jasiukajtis * Constants:
5325c28e83SPiotr Jasiukajtis * The hexadecimal values are the intended ones for the following constants.
5425c28e83SPiotr Jasiukajtis * The decimal values may be used, provided that the compiler will convert
5525c28e83SPiotr Jasiukajtis * from decimal to binary accurately enough to produce the hexadecimal values
5625c28e83SPiotr Jasiukajtis * shown.
5725c28e83SPiotr Jasiukajtis */
5825c28e83SPiotr Jasiukajtis
59*ddc0e0b5SRichard Lowe #pragma weak __atan2l = atan2l
6025c28e83SPiotr Jasiukajtis
6125c28e83SPiotr Jasiukajtis #include "libm.h"
6225c28e83SPiotr Jasiukajtis #include "longdouble.h"
6325c28e83SPiotr Jasiukajtis
6425c28e83SPiotr Jasiukajtis static const long double
6525c28e83SPiotr Jasiukajtis zero = 0.0L,
6625c28e83SPiotr Jasiukajtis tiny = 1.0e-40L,
6725c28e83SPiotr Jasiukajtis one = 1.0L,
6825c28e83SPiotr Jasiukajtis half = 0.5L,
6925c28e83SPiotr Jasiukajtis PI3o4 = 2.356194490192344928846982537459627163148L,
7025c28e83SPiotr Jasiukajtis PIo4 = 0.785398163397448309615660845819875721049L,
7125c28e83SPiotr Jasiukajtis PIo2 = 1.570796326794896619231321691639751442099L,
7225c28e83SPiotr Jasiukajtis PI = 3.141592653589793238462643383279502884197L,
7325c28e83SPiotr Jasiukajtis PI_lo = 8.671810130123781024797044026043351968762e-35L;
7425c28e83SPiotr Jasiukajtis
7525c28e83SPiotr Jasiukajtis long double
atan2l(long double y,long double x)7625c28e83SPiotr Jasiukajtis atan2l(long double y, long double x) {
7725c28e83SPiotr Jasiukajtis long double t, z;
7825c28e83SPiotr Jasiukajtis int k, m, signy, signx;
7925c28e83SPiotr Jasiukajtis
8025c28e83SPiotr Jasiukajtis if (x != x || y != y)
8125c28e83SPiotr Jasiukajtis return (x + y); /* return NaN if x or y is NAN */
8225c28e83SPiotr Jasiukajtis signy = signbitl(y);
8325c28e83SPiotr Jasiukajtis signx = signbitl(x);
8425c28e83SPiotr Jasiukajtis if (x == one)
8525c28e83SPiotr Jasiukajtis return (atanl(y));
8625c28e83SPiotr Jasiukajtis m = signy + signx + signx;
8725c28e83SPiotr Jasiukajtis
8825c28e83SPiotr Jasiukajtis /* when y = 0 */
8925c28e83SPiotr Jasiukajtis if (y == zero)
9025c28e83SPiotr Jasiukajtis switch (m) {
9125c28e83SPiotr Jasiukajtis case 0:
9225c28e83SPiotr Jasiukajtis return (y); /* atan(+0,+anything) */
9325c28e83SPiotr Jasiukajtis case 1:
9425c28e83SPiotr Jasiukajtis return (y); /* atan(-0,+anything) */
9525c28e83SPiotr Jasiukajtis case 2:
9625c28e83SPiotr Jasiukajtis return (PI + tiny); /* atan(+0,-anything) */
9725c28e83SPiotr Jasiukajtis case 3:
9825c28e83SPiotr Jasiukajtis return (-PI - tiny); /* atan(-0,-anything) */
9925c28e83SPiotr Jasiukajtis }
10025c28e83SPiotr Jasiukajtis
10125c28e83SPiotr Jasiukajtis /* when x = 0 */
10225c28e83SPiotr Jasiukajtis if (x == zero)
10325c28e83SPiotr Jasiukajtis return (signy == 1 ? -PIo2 - tiny : PIo2 + tiny);
10425c28e83SPiotr Jasiukajtis
10525c28e83SPiotr Jasiukajtis /* when x is INF */
10625c28e83SPiotr Jasiukajtis if (!finitel(x)) {
10725c28e83SPiotr Jasiukajtis if (!finitel(y)) {
10825c28e83SPiotr Jasiukajtis switch (m) {
10925c28e83SPiotr Jasiukajtis case 0:
11025c28e83SPiotr Jasiukajtis return (PIo4 + tiny); /* atan(+INF,+INF) */
11125c28e83SPiotr Jasiukajtis case 1:
11225c28e83SPiotr Jasiukajtis return (-PIo4 - tiny); /* atan(-INF,+INF) */
11325c28e83SPiotr Jasiukajtis case 2:
11425c28e83SPiotr Jasiukajtis return (PI3o4 + tiny); /* atan(+INF,-INF) */
11525c28e83SPiotr Jasiukajtis case 3:
11625c28e83SPiotr Jasiukajtis return (-PI3o4 - tiny); /* atan(-INF,-INF) */
11725c28e83SPiotr Jasiukajtis }
11825c28e83SPiotr Jasiukajtis } else {
11925c28e83SPiotr Jasiukajtis switch (m) {
12025c28e83SPiotr Jasiukajtis case 0:
12125c28e83SPiotr Jasiukajtis return (zero); /* atan(+...,+INF) */
12225c28e83SPiotr Jasiukajtis case 1:
12325c28e83SPiotr Jasiukajtis return (-zero); /* atan(-...,+INF) */
12425c28e83SPiotr Jasiukajtis case 2:
12525c28e83SPiotr Jasiukajtis return (PI + tiny); /* atan(+...,-INF) */
12625c28e83SPiotr Jasiukajtis case 3:
12725c28e83SPiotr Jasiukajtis return (-PI - tiny); /* atan(-...,-INF) */
12825c28e83SPiotr Jasiukajtis }
12925c28e83SPiotr Jasiukajtis }
13025c28e83SPiotr Jasiukajtis }
13125c28e83SPiotr Jasiukajtis /* when y is INF */
13225c28e83SPiotr Jasiukajtis if (!finitel(y))
13325c28e83SPiotr Jasiukajtis return (signy == 1 ? -PIo2 - tiny : PIo2 + tiny);
13425c28e83SPiotr Jasiukajtis
13525c28e83SPiotr Jasiukajtis /* compute y/x */
13625c28e83SPiotr Jasiukajtis x = fabsl(x);
13725c28e83SPiotr Jasiukajtis y = fabsl(y);
13825c28e83SPiotr Jasiukajtis t = PI_lo;
13925c28e83SPiotr Jasiukajtis k = (ilogbl(y) - ilogbl(x));
14025c28e83SPiotr Jasiukajtis
14125c28e83SPiotr Jasiukajtis if (k > 120)
14225c28e83SPiotr Jasiukajtis z = PIo2 + half * t;
14325c28e83SPiotr Jasiukajtis else if (m > 1 && k < -120)
14425c28e83SPiotr Jasiukajtis z = zero;
14525c28e83SPiotr Jasiukajtis else
14625c28e83SPiotr Jasiukajtis z = atanl(y / x);
14725c28e83SPiotr Jasiukajtis
14825c28e83SPiotr Jasiukajtis switch (m) {
14925c28e83SPiotr Jasiukajtis case 0:
15025c28e83SPiotr Jasiukajtis return (z); /* atan(+,+) */
15125c28e83SPiotr Jasiukajtis case 1:
15225c28e83SPiotr Jasiukajtis return (-z); /* atan(-,+) */
15325c28e83SPiotr Jasiukajtis case 2:
15425c28e83SPiotr Jasiukajtis return (PI - (z - t)); /* atan(+,-) */
15525c28e83SPiotr Jasiukajtis case 3:
15625c28e83SPiotr Jasiukajtis return ((z - t) - PI); /* atan(-,-) */
15725c28e83SPiotr Jasiukajtis }
15825c28e83SPiotr Jasiukajtis /* NOTREACHED */
15925c28e83SPiotr Jasiukajtis return 0.0L;
16025c28e83SPiotr Jasiukajtis }
161