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 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