1*25c28e83SPiotr Jasiukajtis /* 2*25c28e83SPiotr Jasiukajtis * CDDL HEADER START 3*25c28e83SPiotr Jasiukajtis * 4*25c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the 5*25c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License"). 6*25c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License. 7*25c28e83SPiotr Jasiukajtis * 8*25c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*25c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing. 10*25c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions 11*25c28e83SPiotr Jasiukajtis * and limitations under the License. 12*25c28e83SPiotr Jasiukajtis * 13*25c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each 14*25c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*25c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the 16*25c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying 17*25c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner] 18*25c28e83SPiotr Jasiukajtis * 19*25c28e83SPiotr Jasiukajtis * CDDL HEADER END 20*25c28e83SPiotr Jasiukajtis */ 21*25c28e83SPiotr Jasiukajtis /* 22*25c28e83SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 23*25c28e83SPiotr Jasiukajtis */ 24*25c28e83SPiotr Jasiukajtis /* 25*25c28e83SPiotr Jasiukajtis * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 26*25c28e83SPiotr Jasiukajtis * Use is subject to license terms. 27*25c28e83SPiotr Jasiukajtis */ 28*25c28e83SPiotr Jasiukajtis 29*25c28e83SPiotr Jasiukajtis #include "libm.h" /* __k_atan2 */ 30*25c28e83SPiotr Jasiukajtis #include "complex_wrapper.h" 31*25c28e83SPiotr Jasiukajtis 32*25c28e83SPiotr Jasiukajtis /* 33*25c28e83SPiotr Jasiukajtis * double __k_atan2(double y, double x, double *e) 34*25c28e83SPiotr Jasiukajtis * 35*25c28e83SPiotr Jasiukajtis * Compute atan2 with error terms. 36*25c28e83SPiotr Jasiukajtis * 37*25c28e83SPiotr Jasiukajtis * Important formula: 38*25c28e83SPiotr Jasiukajtis * 3 5 39*25c28e83SPiotr Jasiukajtis * x x 40*25c28e83SPiotr Jasiukajtis * atan(x) = x - ----- + ----- - ... (for x <= 1) 41*25c28e83SPiotr Jasiukajtis * 3 5 42*25c28e83SPiotr Jasiukajtis * 43*25c28e83SPiotr Jasiukajtis * pi 1 1 44*25c28e83SPiotr Jasiukajtis * = --- - --- + --- - ... (for x > 1) 45*25c28e83SPiotr Jasiukajtis * 3 46*25c28e83SPiotr Jasiukajtis * 2 x 3x 47*25c28e83SPiotr Jasiukajtis * 48*25c28e83SPiotr Jasiukajtis * Arg(x + y i) = sign(y) * atan2(|y|, x) 49*25c28e83SPiotr Jasiukajtis * = sign(y) * atan(|y|/x) (for x > 0) 50*25c28e83SPiotr Jasiukajtis * sign(y) * (PI - atan(|y|/|x|)) (for x < 0) 51*25c28e83SPiotr Jasiukajtis * Thus if x >> y (IEEE double: EXP(x) - EXP(y) >= 60): 52*25c28e83SPiotr Jasiukajtis * 1. (x > 0): atan2(y,x) ~ y/x 53*25c28e83SPiotr Jasiukajtis * 2. (x < 0): atan2(y,x) ~ sign(y) (PI - |y/x|)) 54*25c28e83SPiotr Jasiukajtis * Otherwise if x << y: 55*25c28e83SPiotr Jasiukajtis * atan2(y,x) ~ sign(y)*PI/2 - x/y 56*25c28e83SPiotr Jasiukajtis * 57*25c28e83SPiotr Jasiukajtis * __k_atan2 call static functions mx_poly, mx_atan 58*25c28e83SPiotr Jasiukajtis */ 59*25c28e83SPiotr Jasiukajtis 60*25c28e83SPiotr Jasiukajtis /* 61*25c28e83SPiotr Jasiukajtis * (void) mx_poly (double *z, double *a, double *e, int n) 62*25c28e83SPiotr Jasiukajtis * return 63*25c28e83SPiotr Jasiukajtis * e = a + z*(a + z*(a + ... z*(a + e)...)) 64*25c28e83SPiotr Jasiukajtis * 0 2 4 2n 65*25c28e83SPiotr Jasiukajtis * Note: 66*25c28e83SPiotr Jasiukajtis * 1. e and coefficient ai are represented by two double numbers. 67*25c28e83SPiotr Jasiukajtis * For e, the first one contain the leading 24 bits rounded, and the 68*25c28e83SPiotr Jasiukajtis * second one contain the remaining 53 bits (total 77 bits accuracy). 69*25c28e83SPiotr Jasiukajtis * For ai, the first one contian the leading 53 bits rounded, and the 70*25c28e83SPiotr Jasiukajtis * second is the remaining 53 bits (total 106 bits accuracy). 71*25c28e83SPiotr Jasiukajtis * 2. z is an array of three doubles. 72*25c28e83SPiotr Jasiukajtis * z[0] : the rounded value of Z (the intended value of z) 73*25c28e83SPiotr Jasiukajtis * z[1] : the leading 24 bits of Z rounded 74*25c28e83SPiotr Jasiukajtis * z[2] : the remaining 53 bits of Z 75*25c28e83SPiotr Jasiukajtis * Note that z[0] = z[1]+z[2] rounded. 76*25c28e83SPiotr Jasiukajtis * 77*25c28e83SPiotr Jasiukajtis */ 78*25c28e83SPiotr Jasiukajtis 79*25c28e83SPiotr Jasiukajtis static void 80*25c28e83SPiotr Jasiukajtis mx_poly(const double *z, const double *a, double *e, int n) { 81*25c28e83SPiotr Jasiukajtis double r, s, t, p_h, p_l, z_h, z_l, p; 82*25c28e83SPiotr Jasiukajtis int i; 83*25c28e83SPiotr Jasiukajtis 84*25c28e83SPiotr Jasiukajtis n = n + n; 85*25c28e83SPiotr Jasiukajtis p = e[0] + a[n]; 86*25c28e83SPiotr Jasiukajtis p_l = a[n + 1]; 87*25c28e83SPiotr Jasiukajtis p_h = (double) ((float) p); 88*25c28e83SPiotr Jasiukajtis p = a[n - 2] + z[0] * p; 89*25c28e83SPiotr Jasiukajtis z_h = z[1]; z_l = z[2]; 90*25c28e83SPiotr Jasiukajtis p_l += e[0] - (p_h - a[n]); 91*25c28e83SPiotr Jasiukajtis 92*25c28e83SPiotr Jasiukajtis for (i = n - 2; i >= 2; i -= 2) { 93*25c28e83SPiotr Jasiukajtis /* compute p = ai + z * p */ 94*25c28e83SPiotr Jasiukajtis t = z_h * p_h; 95*25c28e83SPiotr Jasiukajtis s = z[0] * p_l + p_h * z_l; 96*25c28e83SPiotr Jasiukajtis p_h = (double) ((float) p); 97*25c28e83SPiotr Jasiukajtis s += a[i + 1]; 98*25c28e83SPiotr Jasiukajtis r = t - (p_h - a[i]); 99*25c28e83SPiotr Jasiukajtis p = a[i - 2] + z[0] * p; 100*25c28e83SPiotr Jasiukajtis p_l = r + s; 101*25c28e83SPiotr Jasiukajtis } 102*25c28e83SPiotr Jasiukajtis e[0] = (double)((float) p); 103*25c28e83SPiotr Jasiukajtis t = z_h * p_h; 104*25c28e83SPiotr Jasiukajtis s = z[0] * p_l + p_h * z_l; 105*25c28e83SPiotr Jasiukajtis r = t - (e[0] - a[0]); 106*25c28e83SPiotr Jasiukajtis e[1] = r + s; 107*25c28e83SPiotr Jasiukajtis } 108*25c28e83SPiotr Jasiukajtis 109*25c28e83SPiotr Jasiukajtis /* 110*25c28e83SPiotr Jasiukajtis * Table of constants for atan from 0.125 to 8 111*25c28e83SPiotr Jasiukajtis * 0.125 -- 0x3fc00000 --- (increment at bit 16) 112*25c28e83SPiotr Jasiukajtis * 0x3fc10000 113*25c28e83SPiotr Jasiukajtis * 0x3fc20000 114*25c28e83SPiotr Jasiukajtis * ... ... 115*25c28e83SPiotr Jasiukajtis * 0x401f0000 116*25c28e83SPiotr Jasiukajtis * 8.000 -- 0x40200000 (total: 97) 117*25c28e83SPiotr Jasiukajtis * By K.C. Ng, March 9, 1989 118*25c28e83SPiotr Jasiukajtis */ 119*25c28e83SPiotr Jasiukajtis 120*25c28e83SPiotr Jasiukajtis static const double TBL_atan_hi[] = { 121*25c28e83SPiotr Jasiukajtis 1.243549945467614382e-01, 1.320397616146387620e-01, 1.397088742891636204e-01, 122*25c28e83SPiotr Jasiukajtis 1.473614810886516302e-01, 1.549967419239409727e-01, 1.626138285979485676e-01, 123*25c28e83SPiotr Jasiukajtis 1.702119252854744080e-01, 1.777902289926760471e-01, 1.853479499956947607e-01, 124*25c28e83SPiotr Jasiukajtis 1.928843122579746439e-01, 2.003985538258785115e-01, 2.078899272022629863e-01, 125*25c28e83SPiotr Jasiukajtis 2.153576996977380476e-01, 2.228011537593945213e-01, 2.302195872768437179e-01, 126*25c28e83SPiotr Jasiukajtis 2.376123138654712419e-01, 2.449786631268641435e-01, 2.596296294082575118e-01, 127*25c28e83SPiotr Jasiukajtis 2.741674511196587893e-01, 2.885873618940774099e-01, 3.028848683749714166e-01, 128*25c28e83SPiotr Jasiukajtis 3.170557532091470287e-01, 3.310960767041321029e-01, 3.450021772071051318e-01, 129*25c28e83SPiotr Jasiukajtis 3.587706702705721895e-01, 3.723984466767542023e-01, 3.858826693980737521e-01, 130*25c28e83SPiotr Jasiukajtis 3.992207695752525431e-01, 4.124104415973872673e-01, 4.254496373700422662e-01, 131*25c28e83SPiotr Jasiukajtis 4.383365598579578304e-01, 4.510696559885234436e-01, 4.636476090008060935e-01, 132*25c28e83SPiotr Jasiukajtis 4.883339510564055352e-01, 5.123894603107377321e-01, 5.358112379604637043e-01, 133*25c28e83SPiotr Jasiukajtis 5.585993153435624414e-01, 5.807563535676704136e-01, 6.022873461349641522e-01, 134*25c28e83SPiotr Jasiukajtis 6.231993299340659043e-01, 6.435011087932843710e-01, 6.632029927060932861e-01, 135*25c28e83SPiotr Jasiukajtis 6.823165548747480713e-01, 7.008544078844501923e-01, 7.188299996216245269e-01, 136*25c28e83SPiotr Jasiukajtis 7.362574289814280970e-01, 7.531512809621944138e-01, 7.695264804056582975e-01, 137*25c28e83SPiotr Jasiukajtis 7.853981633974482790e-01, 8.156919233162234217e-01, 8.441539861131710509e-01, 138*25c28e83SPiotr Jasiukajtis 8.709034570756529758e-01, 8.960553845713439269e-01, 9.197196053504168578e-01, 139*25c28e83SPiotr Jasiukajtis 9.420000403794636101e-01, 9.629943306809362058e-01, 9.827937232473290541e-01, 140*25c28e83SPiotr Jasiukajtis 1.001483135694234639e+00, 1.019141344266349725e+00, 1.035841253008800145e+00, 141*25c28e83SPiotr Jasiukajtis 1.051650212548373764e+00, 1.066630365315743623e+00, 1.080839000541168327e+00, 142*25c28e83SPiotr Jasiukajtis 1.094328907321189925e+00, 1.107148717794090409e+00, 1.130953743979160375e+00, 143*25c28e83SPiotr Jasiukajtis 1.152571997215667610e+00, 1.172273881128476303e+00, 1.190289949682531656e+00, 144*25c28e83SPiotr Jasiukajtis 1.206817370285252489e+00, 1.222025323210989667e+00, 1.236059489478081863e+00, 145*25c28e83SPiotr Jasiukajtis 1.249045772398254428e+00, 1.261093382252440387e+00, 1.272297395208717319e+00, 146*25c28e83SPiotr Jasiukajtis 1.282740879744270757e+00, 1.292496667789785336e+00, 1.301628834009196156e+00, 147*25c28e83SPiotr Jasiukajtis 1.310193935047555547e+00, 1.318242051016837113e+00, 1.325817663668032553e+00, 148*25c28e83SPiotr Jasiukajtis 1.339705659598999565e+00, 1.352127380920954636e+00, 1.363300100359693845e+00, 149*25c28e83SPiotr Jasiukajtis 1.373400766945015894e+00, 1.382574821490125894e+00, 1.390942827002418447e+00, 150*25c28e83SPiotr Jasiukajtis 1.398605512271957618e+00, 1.405647649380269870e+00, 1.412141064608495311e+00, 151*25c28e83SPiotr Jasiukajtis 1.418146998399631542e+00, 1.423717971406494032e+00, 1.428899272190732761e+00, 152*25c28e83SPiotr Jasiukajtis 1.433730152484709031e+00, 1.438244794498222623e+00, 1.442473099109101931e+00, 153*25c28e83SPiotr Jasiukajtis 1.446441332248135092e+00, 154*25c28e83SPiotr Jasiukajtis }; 155*25c28e83SPiotr Jasiukajtis 156*25c28e83SPiotr Jasiukajtis static const double TBL_atan_lo[] = { 157*25c28e83SPiotr Jasiukajtis -3.125324142453938311e-18, -1.276925400709959526e-17, 2.479758919089733066e-17, 158*25c28e83SPiotr Jasiukajtis 5.409599147666297957e-18, 9.585415594114323829e-18, 7.784470643106252464e-18, 159*25c28e83SPiotr Jasiukajtis -3.541164079802125137e-18, 2.372599351477449041e-17, 4.180692268843078977e-18, 160*25c28e83SPiotr Jasiukajtis 2.034098543938166622e-17, 3.139954287184449286e-18, 7.333160666520898500e-18, 161*25c28e83SPiotr Jasiukajtis 4.738160130078732886e-19, -5.498822172446843173e-18, 1.231340452914270316e-17, 162*25c28e83SPiotr Jasiukajtis 1.058231431371112987e-17, 1.069875561873445139e-17, 1.923875492461530410e-17, 163*25c28e83SPiotr Jasiukajtis 8.261353575163771936e-18, -1.428369957377257085e-17, -1.101082790300136900e-17, 164*25c28e83SPiotr Jasiukajtis -1.893928924292642146e-17, -7.952610375793798701e-18, -2.293880475557830393e-17, 165*25c28e83SPiotr Jasiukajtis 3.088733564861919217e-17, 1.961231150484565340e-17, 2.378822732491940868e-17, 166*25c28e83SPiotr Jasiukajtis 2.246598105617042065e-17, 3.963462895355093301e-17, 2.331553074189288466e-17, 167*25c28e83SPiotr Jasiukajtis -2.494277030626540909e-17, 3.280735600183735558e-17, 2.269877745296168709e-17, 168*25c28e83SPiotr Jasiukajtis -1.137323618932958456e-17, -2.546278147285580353e-17, -4.063795683482557497e-18, 169*25c28e83SPiotr Jasiukajtis -5.455630548591626394e-18, -1.441464378193066908e-17, 2.950430737228402307e-17, 170*25c28e83SPiotr Jasiukajtis 2.672403885140095079e-17, 1.583478505144428617e-17, -3.076054864429649001e-17, 171*25c28e83SPiotr Jasiukajtis 6.943223671560007740e-18, -1.987626234335816123e-17, -2.147838844445698302e-17, 172*25c28e83SPiotr Jasiukajtis 3.473937648299456719e-17, -2.425693465918206812e-17, -3.704991905602721293e-17, 173*25c28e83SPiotr Jasiukajtis 3.061616997868383018e-17, -1.071456562778743077e-17, -4.841337011934916763e-17, 174*25c28e83SPiotr Jasiukajtis -2.269823590747287052e-17, 2.923876285774304890e-17, -4.057439412852767923e-17, 175*25c28e83SPiotr Jasiukajtis 5.460837485846687627e-17, -3.986660595210752445e-18, 1.390331103123099845e-17, 176*25c28e83SPiotr Jasiukajtis 9.438308023545392000e-17, 1.000401886936679889e-17, 3.194313981784503706e-17, 177*25c28e83SPiotr Jasiukajtis -9.650564731467513515e-17, -5.956589637160374564e-17, -1.567632251135907253e-17, 178*25c28e83SPiotr Jasiukajtis -5.490676155022364226e-18, 9.404471373566379412e-17, 7.123833804538446299e-17, 179*25c28e83SPiotr Jasiukajtis -9.159738508900378819e-17, 8.385188614028674371e-17, 7.683333629842068806e-17, 180*25c28e83SPiotr Jasiukajtis 4.172467638861439118e-17, -2.979162864892849274e-17, 7.879752739459421280e-17, 181*25c28e83SPiotr Jasiukajtis -2.196203799612310905e-18, 3.242139621534960503e-17, 2.245875015034507026e-17, 182*25c28e83SPiotr Jasiukajtis -9.283188754266129476e-18, -6.830804768926660334e-17, -1.236918499824626670e-17, 183*25c28e83SPiotr Jasiukajtis 8.745413734780278834e-17, -6.319394031144676258e-17, -8.824429373951136321e-17, 184*25c28e83SPiotr Jasiukajtis -2.599011860304134377e-17, 2.147674250751150961e-17, 1.093246171526936217e-16, 185*25c28e83SPiotr Jasiukajtis -3.307710355769516504e-17, -3.561490438648230100e-17, -9.843712133488842595e-17, 186*25c28e83SPiotr Jasiukajtis -2.324061182591627982e-17, -8.922630138234492386e-17, -9.573807110557223276e-17, 187*25c28e83SPiotr Jasiukajtis -8.263883782511013632e-17, 8.721870922223967507e-17, -6.457134743238754385e-17, 188*25c28e83SPiotr Jasiukajtis -4.396204466767636187e-17, -2.493019910264565554e-17, -1.105119435430315713e-16, 189*25c28e83SPiotr Jasiukajtis 9.211323971545051565e-17, 190*25c28e83SPiotr Jasiukajtis }; 191*25c28e83SPiotr Jasiukajtis 192*25c28e83SPiotr Jasiukajtis /* 193*25c28e83SPiotr Jasiukajtis * mx_atan(x,err) 194*25c28e83SPiotr Jasiukajtis * Table look-up algorithm 195*25c28e83SPiotr Jasiukajtis * By K.C. Ng, March 9, 1989 196*25c28e83SPiotr Jasiukajtis * 197*25c28e83SPiotr Jasiukajtis * Algorithm. 198*25c28e83SPiotr Jasiukajtis * 199*25c28e83SPiotr Jasiukajtis * The algorithm is based on atan(x)=atan(y)+atan((x-y)/(1+x*y)). 200*25c28e83SPiotr Jasiukajtis * We use poly1(x) to approximate atan(x) for x in [0,1/8] with 201*25c28e83SPiotr Jasiukajtis * error (relative) 202*25c28e83SPiotr Jasiukajtis * |(atan(x)-poly1(x))/x|<= 2^-83.41 203*25c28e83SPiotr Jasiukajtis * 204*25c28e83SPiotr Jasiukajtis * and use poly2(x) to approximate atan(x) for x in [0,1/65] with 205*25c28e83SPiotr Jasiukajtis * error 206*25c28e83SPiotr Jasiukajtis * |atan(x)-poly2(x)|<= 2^-86.8 207*25c28e83SPiotr Jasiukajtis * 208*25c28e83SPiotr Jasiukajtis * Here poly1 and poly2 are odd polynomial with the following form: 209*25c28e83SPiotr Jasiukajtis * x + x^3*(a1+x^2*(a2+...)) 210*25c28e83SPiotr Jasiukajtis * 211*25c28e83SPiotr Jasiukajtis * (0). Purge off Inf and NaN and 0 212*25c28e83SPiotr Jasiukajtis * (1). Reduce x to positive by atan(x) = -atan(-x). 213*25c28e83SPiotr Jasiukajtis * (2). For x <= 1/8, use 214*25c28e83SPiotr Jasiukajtis * (2.1) if x < 2^(-prec/2), atan(x) = x with inexact flag raised 215*25c28e83SPiotr Jasiukajtis * (2.2) Otherwise 216*25c28e83SPiotr Jasiukajtis * atan(x) = poly1(x) 217*25c28e83SPiotr Jasiukajtis * (3). For x >= 8 then (prec = 78) 218*25c28e83SPiotr Jasiukajtis * (3.1) if x >= 2^prec, atan(x) = atan(inf) - pio2lo 219*25c28e83SPiotr Jasiukajtis * (3.2) if x >= 2^(prec/3), atan(x) = atan(inf) - 1/x 220*25c28e83SPiotr Jasiukajtis * (3.3) if x > 65, atan(x) = atan(inf) - poly2(1/x) 221*25c28e83SPiotr Jasiukajtis * (3.4) Otherwise, atan(x) = atan(inf) - poly1(1/x) 222*25c28e83SPiotr Jasiukajtis * 223*25c28e83SPiotr Jasiukajtis * (4). Now x is in (0.125, 8) 224*25c28e83SPiotr Jasiukajtis * Find y that match x to 4.5 bit after binary (easy). 225*25c28e83SPiotr Jasiukajtis * If iy is the high word of y, then 226*25c28e83SPiotr Jasiukajtis * single : j = (iy - 0x3e000000) >> 19 227*25c28e83SPiotr Jasiukajtis * double : j = (iy - 0x3fc00000) >> 16 228*25c28e83SPiotr Jasiukajtis * quad : j = (iy - 0x3ffc0000) >> 12 229*25c28e83SPiotr Jasiukajtis * 230*25c28e83SPiotr Jasiukajtis * Let s = (x-y)/(1+x*y). Then 231*25c28e83SPiotr Jasiukajtis * atan(x) = atan(y) + poly1(s) 232*25c28e83SPiotr Jasiukajtis * = _TBL_atan_hi[j] + (_TBL_atan_lo[j] + poly2(s) ) 233*25c28e83SPiotr Jasiukajtis * 234*25c28e83SPiotr Jasiukajtis * Note. |s| <= 1.5384615385e-02 = 1/65. Maxium occurs at x = 1.03125 235*25c28e83SPiotr Jasiukajtis * 236*25c28e83SPiotr Jasiukajtis */ 237*25c28e83SPiotr Jasiukajtis 238*25c28e83SPiotr Jasiukajtis #define P1 p[2] 239*25c28e83SPiotr Jasiukajtis #define P4 p[8] 240*25c28e83SPiotr Jasiukajtis #define P5 p[9] 241*25c28e83SPiotr Jasiukajtis #define P6 p[10] 242*25c28e83SPiotr Jasiukajtis #define P7 p[11] 243*25c28e83SPiotr Jasiukajtis #define P8 p[12] 244*25c28e83SPiotr Jasiukajtis #define P9 p[13] 245*25c28e83SPiotr Jasiukajtis static const double p[] = { 246*25c28e83SPiotr Jasiukajtis 1.0, 247*25c28e83SPiotr Jasiukajtis 0.0, 248*25c28e83SPiotr Jasiukajtis -3.33333333333333314830e-01, /* p1 = BFD55555 55555555 */ 249*25c28e83SPiotr Jasiukajtis -1.85030852238476921863e-17, /* p1_l = BC755525 9783A49C */ 250*25c28e83SPiotr Jasiukajtis 2.00000000000000011102e-01, /* p2 = 3FC99999 9999999A */ 251*25c28e83SPiotr Jasiukajtis -1.27263196576150347368e-17, /* p2_l = BC6D584B 0D874007 */ 252*25c28e83SPiotr Jasiukajtis -1.42857142857141405923e-01, /* p3 = BFC24924 9249245E */ 253*25c28e83SPiotr Jasiukajtis -1.34258204847170493327e-17, /* p3_l = BC6EF534 A112500D */ 254*25c28e83SPiotr Jasiukajtis 1.11111111110486909803e-01, /* p4 = 3FBC71C7 1C71176A */ 255*25c28e83SPiotr Jasiukajtis -9.09090907557387889470e-02, /* p5 = BFB745D1 73B47A7D */ 256*25c28e83SPiotr Jasiukajtis 7.69230541541713053189e-02, /* p6 = 3FB3B13A B1E68DE6 */ 257*25c28e83SPiotr Jasiukajtis -6.66645815401964159097e-02, /* p7 = BFB110EE 1584446A */ 258*25c28e83SPiotr Jasiukajtis 5.87081768778560317279e-02, /* p8 = 3FAE0EFF 87657733 */ 259*25c28e83SPiotr Jasiukajtis -4.90818147456113240690e-02, /* p9 = BFA92140 6A524B5C */ 260*25c28e83SPiotr Jasiukajtis }; 261*25c28e83SPiotr Jasiukajtis #define Q1 q[2] 262*25c28e83SPiotr Jasiukajtis #define Q3 q[6] 263*25c28e83SPiotr Jasiukajtis #define Q4 q[7] 264*25c28e83SPiotr Jasiukajtis #define Q5 q[8] 265*25c28e83SPiotr Jasiukajtis static const double q[] = { 266*25c28e83SPiotr Jasiukajtis 1.0, 267*25c28e83SPiotr Jasiukajtis 0.0, 268*25c28e83SPiotr Jasiukajtis -3.33333333333333314830e-01, /* q1 = BFD55555 55555555 */ 269*25c28e83SPiotr Jasiukajtis -1.85022941571278638733e-17, /* q1_l = BC7554E9 D20EFA66 */ 270*25c28e83SPiotr Jasiukajtis 1.99999999999999927836e-01, /* q2 = 3FC99999 99999997 */ 271*25c28e83SPiotr Jasiukajtis -1.28782564407438833398e-17, /* q2_l = BC6DB1FB 17217417 */ 272*25c28e83SPiotr Jasiukajtis -1.42857142855492280642e-01, /* q3 = BFC24924 92483C46 */ 273*25c28e83SPiotr Jasiukajtis 1.11111097130183356096e-01, /* q4 = 3FBC71C6 E06595CC */ 274*25c28e83SPiotr Jasiukajtis -9.08553303569109294013e-02, /* q5 = BFB7424B 808CDA76 */ 275*25c28e83SPiotr Jasiukajtis }; 276*25c28e83SPiotr Jasiukajtis static const double 277*25c28e83SPiotr Jasiukajtis one = 1.0, 278*25c28e83SPiotr Jasiukajtis pio2hi = 1.570796326794896558e+00, 279*25c28e83SPiotr Jasiukajtis pio2lo = 6.123233995736765886e-17; 280*25c28e83SPiotr Jasiukajtis 281*25c28e83SPiotr Jasiukajtis static double 282*25c28e83SPiotr Jasiukajtis mx_atan(double x, double *err) { 283*25c28e83SPiotr Jasiukajtis double y, z, r, s, t, w, s_h, s_l, x_h, x_l, zz[3], ee[2], z_h, 284*25c28e83SPiotr Jasiukajtis z_l, r_h, r_l, u, v; 285*25c28e83SPiotr Jasiukajtis int ix, iy, sign, j; 286*25c28e83SPiotr Jasiukajtis 287*25c28e83SPiotr Jasiukajtis ix = ((int *) &x)[HIWORD]; 288*25c28e83SPiotr Jasiukajtis sign = ix & 0x80000000; 289*25c28e83SPiotr Jasiukajtis ix ^= sign; 290*25c28e83SPiotr Jasiukajtis 291*25c28e83SPiotr Jasiukajtis /* for |x| < 1/8 */ 292*25c28e83SPiotr Jasiukajtis if (ix < 0x3fc00000) { 293*25c28e83SPiotr Jasiukajtis if (ix < 0x3f300000) { /* when |x| < 2**-12 */ 294*25c28e83SPiotr Jasiukajtis if (ix < 0x3d800000) { /* if |x| < 2**-39 */ 295*25c28e83SPiotr Jasiukajtis *err = (double) ((int) x); 296*25c28e83SPiotr Jasiukajtis return (x); 297*25c28e83SPiotr Jasiukajtis } 298*25c28e83SPiotr Jasiukajtis z = x * x; 299*25c28e83SPiotr Jasiukajtis t = x * z * (q[2] + z * (q[4] + z * q[6])); 300*25c28e83SPiotr Jasiukajtis r = x + t; 301*25c28e83SPiotr Jasiukajtis *err = t - (r - x); 302*25c28e83SPiotr Jasiukajtis return (r); 303*25c28e83SPiotr Jasiukajtis } 304*25c28e83SPiotr Jasiukajtis z = x * x; 305*25c28e83SPiotr Jasiukajtis 306*25c28e83SPiotr Jasiukajtis /* use double precision at p4 and on */ 307*25c28e83SPiotr Jasiukajtis ee[0] = z * 308*25c28e83SPiotr Jasiukajtis (P4 + z * 309*25c28e83SPiotr Jasiukajtis (P5 + z * (P6 + z * (P7 + z * (P8 + z * P9))))); 310*25c28e83SPiotr Jasiukajtis 311*25c28e83SPiotr Jasiukajtis x_h = (double) ((float) x); 312*25c28e83SPiotr Jasiukajtis z_h = (double) ((float) z); 313*25c28e83SPiotr Jasiukajtis x_l = x - x_h; 314*25c28e83SPiotr Jasiukajtis z_l = (x_h * x_h - z_h); 315*25c28e83SPiotr Jasiukajtis zz[0] = z; 316*25c28e83SPiotr Jasiukajtis zz[1] = z_h; 317*25c28e83SPiotr Jasiukajtis zz[2] = z_l + x_l * (x + x_h); 318*25c28e83SPiotr Jasiukajtis 319*25c28e83SPiotr Jasiukajtis /* 320*25c28e83SPiotr Jasiukajtis * compute (1+z*(p1+z*(p2+z*(p3+e)))) by call 321*25c28e83SPiotr Jasiukajtis * mx_poly 322*25c28e83SPiotr Jasiukajtis */ 323*25c28e83SPiotr Jasiukajtis 324*25c28e83SPiotr Jasiukajtis mx_poly(zz, p, ee, 3); 325*25c28e83SPiotr Jasiukajtis 326*25c28e83SPiotr Jasiukajtis /* finally x*(1+z*(p1+...)) */ 327*25c28e83SPiotr Jasiukajtis r = x_h * ee[0]; 328*25c28e83SPiotr Jasiukajtis t = x * ee[1] + x_l * ee[0]; 329*25c28e83SPiotr Jasiukajtis s = t + r; 330*25c28e83SPiotr Jasiukajtis *err = t - (s - r); 331*25c28e83SPiotr Jasiukajtis return (s); 332*25c28e83SPiotr Jasiukajtis } 333*25c28e83SPiotr Jasiukajtis /* for |x| >= 8.0 */ 334*25c28e83SPiotr Jasiukajtis if (ix >= 0x40200000) { /* x >= 8 */ 335*25c28e83SPiotr Jasiukajtis x = fabs(x); 336*25c28e83SPiotr Jasiukajtis if (ix >= 0x42600000) { /* x >= 2**39 */ 337*25c28e83SPiotr Jasiukajtis if (ix >= 0x44c00000) { /* x >= 2**77 */ 338*25c28e83SPiotr Jasiukajtis y = -pio2lo; 339*25c28e83SPiotr Jasiukajtis } else 340*25c28e83SPiotr Jasiukajtis y = one / x - pio2lo; 341*25c28e83SPiotr Jasiukajtis if (sign == 0) { 342*25c28e83SPiotr Jasiukajtis t = pio2hi - y; 343*25c28e83SPiotr Jasiukajtis *err = -(y - (pio2hi - t)); 344*25c28e83SPiotr Jasiukajtis } else { 345*25c28e83SPiotr Jasiukajtis t = y - pio2hi; 346*25c28e83SPiotr Jasiukajtis *err = y - (pio2hi + t); 347*25c28e83SPiotr Jasiukajtis } 348*25c28e83SPiotr Jasiukajtis return (t); 349*25c28e83SPiotr Jasiukajtis } else { 350*25c28e83SPiotr Jasiukajtis /* compute r = 1/x */ 351*25c28e83SPiotr Jasiukajtis r = one / x; 352*25c28e83SPiotr Jasiukajtis z = r * r; 353*25c28e83SPiotr Jasiukajtis if (ix < 0x40504000) { /* 8 < x < 65 */ 354*25c28e83SPiotr Jasiukajtis 355*25c28e83SPiotr Jasiukajtis /* use double precision at p4 and on */ 356*25c28e83SPiotr Jasiukajtis ee[0] = z * 357*25c28e83SPiotr Jasiukajtis (P4 + z * 358*25c28e83SPiotr Jasiukajtis (P5 + z * 359*25c28e83SPiotr Jasiukajtis (P6 + z * (P7 + z * (P8 + z * P9))))); 360*25c28e83SPiotr Jasiukajtis x_h = (double) ((float) x); 361*25c28e83SPiotr Jasiukajtis r_h = (double) ((float) r); 362*25c28e83SPiotr Jasiukajtis z_h = (double) ((float) z); 363*25c28e83SPiotr Jasiukajtis r_l = r * ((x_h - x) * r_h - (x_h * r_h - one)); 364*25c28e83SPiotr Jasiukajtis z_l = (r_h * r_h - z_h); 365*25c28e83SPiotr Jasiukajtis zz[0] = z; 366*25c28e83SPiotr Jasiukajtis zz[1] = z_h; 367*25c28e83SPiotr Jasiukajtis zz[2] = z_l + r_l * (r + r_h); 368*25c28e83SPiotr Jasiukajtis /* 369*25c28e83SPiotr Jasiukajtis * compute (1+z*(p1+z*(p2+z*(p3+e)))) by call 370*25c28e83SPiotr Jasiukajtis * mx_poly 371*25c28e83SPiotr Jasiukajtis */ 372*25c28e83SPiotr Jasiukajtis mx_poly(zz, p, ee, 3); 373*25c28e83SPiotr Jasiukajtis } else { /* x < 65 < 2**39 */ 374*25c28e83SPiotr Jasiukajtis /* use double precision at q3 and on */ 375*25c28e83SPiotr Jasiukajtis ee[0] = z * (Q3 + z * (Q4 + z * Q5)); 376*25c28e83SPiotr Jasiukajtis x_h = (double) ((float) x); 377*25c28e83SPiotr Jasiukajtis r_h = (double) ((float) r); 378*25c28e83SPiotr Jasiukajtis z_h = (double) ((float) z); 379*25c28e83SPiotr Jasiukajtis r_l = r * ((x_h - x) * r_h - (x_h * r_h - one)); 380*25c28e83SPiotr Jasiukajtis z_l = (r_h * r_h - z_h); 381*25c28e83SPiotr Jasiukajtis zz[0] = z; 382*25c28e83SPiotr Jasiukajtis zz[1] = z_h; 383*25c28e83SPiotr Jasiukajtis zz[2] = z_l + r_l * (r + r_h); 384*25c28e83SPiotr Jasiukajtis /* 385*25c28e83SPiotr Jasiukajtis * compute (1+z*(q1+z*(q2+e))) by call 386*25c28e83SPiotr Jasiukajtis * mx_poly 387*25c28e83SPiotr Jasiukajtis */ 388*25c28e83SPiotr Jasiukajtis mx_poly(zz, q, ee, 2); 389*25c28e83SPiotr Jasiukajtis } 390*25c28e83SPiotr Jasiukajtis /* pio2 - r*(1+...) */ 391*25c28e83SPiotr Jasiukajtis v = r_h * ee[0]; 392*25c28e83SPiotr Jasiukajtis t = pio2lo - (r * ee[1] + r_l * ee[0]); 393*25c28e83SPiotr Jasiukajtis if (sign == 0) { 394*25c28e83SPiotr Jasiukajtis s = pio2hi - v; 395*25c28e83SPiotr Jasiukajtis t -= (v - (pio2hi - s)); 396*25c28e83SPiotr Jasiukajtis } else { 397*25c28e83SPiotr Jasiukajtis s = v - pio2hi; 398*25c28e83SPiotr Jasiukajtis t = -(t - (v - (s + pio2hi))); 399*25c28e83SPiotr Jasiukajtis } 400*25c28e83SPiotr Jasiukajtis w = s + t; 401*25c28e83SPiotr Jasiukajtis *err = t - (w - s); 402*25c28e83SPiotr Jasiukajtis return (w); 403*25c28e83SPiotr Jasiukajtis } 404*25c28e83SPiotr Jasiukajtis } 405*25c28e83SPiotr Jasiukajtis /* now x is between 1/8 and 8 */ 406*25c28e83SPiotr Jasiukajtis ((int *) &x)[HIWORD] = ix; 407*25c28e83SPiotr Jasiukajtis iy = (ix + 0x00008000) & 0x7fff0000; 408*25c28e83SPiotr Jasiukajtis ((int *) &y)[HIWORD] = iy; 409*25c28e83SPiotr Jasiukajtis ((int *) &y)[LOWORD] = 0; 410*25c28e83SPiotr Jasiukajtis j = (iy - 0x3fc00000) >> 16; 411*25c28e83SPiotr Jasiukajtis 412*25c28e83SPiotr Jasiukajtis w = (x - y); 413*25c28e83SPiotr Jasiukajtis v = 1 / (one + x * y); 414*25c28e83SPiotr Jasiukajtis s = w * v; 415*25c28e83SPiotr Jasiukajtis z = s * s; 416*25c28e83SPiotr Jasiukajtis /* use double precision at q3 and on */ 417*25c28e83SPiotr Jasiukajtis ee[0] = z * (Q3 + z * (Q4 + z * Q5)); 418*25c28e83SPiotr Jasiukajtis s_h = (double) ((float) s); 419*25c28e83SPiotr Jasiukajtis z_h = (double) ((float) z); 420*25c28e83SPiotr Jasiukajtis x_h = (double) ((float) x); 421*25c28e83SPiotr Jasiukajtis t = (double) ((float) (one + x * y)); 422*25c28e83SPiotr Jasiukajtis r = -((x_h - x) * y - (x_h * y - (t - one))); 423*25c28e83SPiotr Jasiukajtis s_l = -v * (s_h * r - (w - s_h * t)); 424*25c28e83SPiotr Jasiukajtis z_l = (s_h * s_h - z_h); 425*25c28e83SPiotr Jasiukajtis zz[0] = z; 426*25c28e83SPiotr Jasiukajtis zz[1] = z_h; 427*25c28e83SPiotr Jasiukajtis zz[2] = z_l + s_l * (s + s_h); 428*25c28e83SPiotr Jasiukajtis /* compute (1+z*(q1+z*(q2+e))) by call mx_poly */ 429*25c28e83SPiotr Jasiukajtis mx_poly(zz, q, ee, 2); 430*25c28e83SPiotr Jasiukajtis v = s_h * ee[0]; 431*25c28e83SPiotr Jasiukajtis t = TBL_atan_lo[j] + (s * ee[1] + s_l * ee[0]); 432*25c28e83SPiotr Jasiukajtis u = TBL_atan_hi[j]; 433*25c28e83SPiotr Jasiukajtis s = u + v; 434*25c28e83SPiotr Jasiukajtis t += (v - (s - u)); 435*25c28e83SPiotr Jasiukajtis w = s + t; 436*25c28e83SPiotr Jasiukajtis *err = t - (w - s); 437*25c28e83SPiotr Jasiukajtis if (sign != 0) { 438*25c28e83SPiotr Jasiukajtis w = -w; 439*25c28e83SPiotr Jasiukajtis *err = -*err; 440*25c28e83SPiotr Jasiukajtis } 441*25c28e83SPiotr Jasiukajtis return (w); 442*25c28e83SPiotr Jasiukajtis } 443*25c28e83SPiotr Jasiukajtis 444*25c28e83SPiotr Jasiukajtis static const double 445*25c28e83SPiotr Jasiukajtis twom768 = 6.441148769597133308e-232, /* 2^-768 */ 446*25c28e83SPiotr Jasiukajtis two768 = 1.552518092300708935e+231, /* 2^768 */ 447*25c28e83SPiotr Jasiukajtis pi = 3.1415926535897931159979634685, 448*25c28e83SPiotr Jasiukajtis pi_lo = 1.224646799147353177e-16, 449*25c28e83SPiotr Jasiukajtis pio2 = 1.570796326794896558e+00, 450*25c28e83SPiotr Jasiukajtis pio2_lo = 6.123233995736765886e-17, 451*25c28e83SPiotr Jasiukajtis pio4 = 0.78539816339744827899949, 452*25c28e83SPiotr Jasiukajtis pio4_lo = 3.061616997868382943e-17, 453*25c28e83SPiotr Jasiukajtis pi3o4 = 2.356194490192344836998, 454*25c28e83SPiotr Jasiukajtis pi3o4_lo = 9.184850993605148829195e-17; 455*25c28e83SPiotr Jasiukajtis 456*25c28e83SPiotr Jasiukajtis double 457*25c28e83SPiotr Jasiukajtis __k_atan2(double y, double x, double *w) { 458*25c28e83SPiotr Jasiukajtis double t, xh, th, t1, t2, w1, w2; 459*25c28e83SPiotr Jasiukajtis int ix, iy, hx, hy, lx, ly; 460*25c28e83SPiotr Jasiukajtis 461*25c28e83SPiotr Jasiukajtis hy = ((int *) &y)[HIWORD]; 462*25c28e83SPiotr Jasiukajtis ly = ((int *) &y)[LOWORD]; 463*25c28e83SPiotr Jasiukajtis iy = hy & ~0x80000000; 464*25c28e83SPiotr Jasiukajtis 465*25c28e83SPiotr Jasiukajtis hx = ((int *) &x)[HIWORD]; 466*25c28e83SPiotr Jasiukajtis lx = ((int *) &x)[LOWORD]; 467*25c28e83SPiotr Jasiukajtis ix = hx & ~0x80000000; 468*25c28e83SPiotr Jasiukajtis 469*25c28e83SPiotr Jasiukajtis *w = 0.0; 470*25c28e83SPiotr Jasiukajtis if (ix >= 0x7ff00000 || iy >= 0x7ff00000) { /* ignore inexact */ 471*25c28e83SPiotr Jasiukajtis if (isnan(x) || isnan(y)) 472*25c28e83SPiotr Jasiukajtis return (x * y); 473*25c28e83SPiotr Jasiukajtis else if (iy < 0x7ff00000) { 474*25c28e83SPiotr Jasiukajtis if (hx >= 0) { /* ATAN2(+-finite, +inf) is +-0 */ 475*25c28e83SPiotr Jasiukajtis *w *= y; 476*25c28e83SPiotr Jasiukajtis return (*w); 477*25c28e83SPiotr Jasiukajtis } else { /* ATAN2(+-finite, -inf) is +-pi */ 478*25c28e83SPiotr Jasiukajtis *w = copysign(pi_lo, y); 479*25c28e83SPiotr Jasiukajtis return (copysign(pi, y)); 480*25c28e83SPiotr Jasiukajtis } 481*25c28e83SPiotr Jasiukajtis } else if (ix < 0x7ff00000) { 482*25c28e83SPiotr Jasiukajtis /* ATAN2(+-inf, finite) is +-pi/2 */ 483*25c28e83SPiotr Jasiukajtis *w = (hy >= 0)? pio2_lo : -pio2_lo; 484*25c28e83SPiotr Jasiukajtis return ((hy >= 0)? pio2 : -pio2); 485*25c28e83SPiotr Jasiukajtis } else if (hx > 0) { /* ATAN2(+-INF,+INF) = +-pi/4 */ 486*25c28e83SPiotr Jasiukajtis *w = (hy >= 0)? pio4_lo : -pio4_lo; 487*25c28e83SPiotr Jasiukajtis return ((hy >= 0)? pio4 : -pio4); 488*25c28e83SPiotr Jasiukajtis } else { /* ATAN2(+-INF,-INF) = +-3pi/4 */ 489*25c28e83SPiotr Jasiukajtis *w = (hy >= 0)? pi3o4_lo : -pi3o4_lo; 490*25c28e83SPiotr Jasiukajtis return ((hy >= 0)? pi3o4 : -pi3o4); 491*25c28e83SPiotr Jasiukajtis } 492*25c28e83SPiotr Jasiukajtis } else if ((ix | lx) == 0 || (iy | ly) == 0) { 493*25c28e83SPiotr Jasiukajtis if ((iy | ly) == 0) { 494*25c28e83SPiotr Jasiukajtis if (hx >= 0) /* ATAN2(+-0, +(0 <= x <= inf)) is +-0 */ 495*25c28e83SPiotr Jasiukajtis return (y); 496*25c28e83SPiotr Jasiukajtis else { /* ATAN2(+-0, -(0 <= x <= inf)) is +-pi */ 497*25c28e83SPiotr Jasiukajtis *w = (hy >= 0)? pi_lo : -pi_lo; 498*25c28e83SPiotr Jasiukajtis return ((hy >= 0)? pi : -pi); 499*25c28e83SPiotr Jasiukajtis } 500*25c28e83SPiotr Jasiukajtis } else { /* ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2 */ 501*25c28e83SPiotr Jasiukajtis *w = (hy >= 0)? pio2_lo : -pio2_lo; 502*25c28e83SPiotr Jasiukajtis return ((hy >= 0)? pio2 : -pio2); 503*25c28e83SPiotr Jasiukajtis } 504*25c28e83SPiotr Jasiukajtis } else if (iy - ix > 0x06400000) { /* |x/y| < 2 ** -100 */ 505*25c28e83SPiotr Jasiukajtis *w = (hy >= 0)? pio2_lo : -pio2_lo; 506*25c28e83SPiotr Jasiukajtis return ((hy >= 0)? pio2 : -pio2); 507*25c28e83SPiotr Jasiukajtis } else if (ix - iy > 0x06400000) { /* |y/x| < 2 ** -100 */ 508*25c28e83SPiotr Jasiukajtis if (hx < 0) { 509*25c28e83SPiotr Jasiukajtis *w = (hy >= 0)? pi_lo : -pi_lo; 510*25c28e83SPiotr Jasiukajtis return ((hy >= 0)? pi : -pi); 511*25c28e83SPiotr Jasiukajtis } else { 512*25c28e83SPiotr Jasiukajtis t = y / x; 513*25c28e83SPiotr Jasiukajtis th = t; 514*25c28e83SPiotr Jasiukajtis ((int *) &th)[LOWORD] &= 0xf8000000; 515*25c28e83SPiotr Jasiukajtis xh = x; 516*25c28e83SPiotr Jasiukajtis ((int *) &xh)[LOWORD] &= 0xf8000000; 517*25c28e83SPiotr Jasiukajtis t1 = (x - xh) * t + xh * (t - th); 518*25c28e83SPiotr Jasiukajtis t2 = y - xh * th; 519*25c28e83SPiotr Jasiukajtis *w = (t2 - t1) / x; 520*25c28e83SPiotr Jasiukajtis return (t); 521*25c28e83SPiotr Jasiukajtis } 522*25c28e83SPiotr Jasiukajtis } else { 523*25c28e83SPiotr Jasiukajtis if (ix >= 0x5f300000) { 524*25c28e83SPiotr Jasiukajtis x *= twom768; 525*25c28e83SPiotr Jasiukajtis y *= twom768; 526*25c28e83SPiotr Jasiukajtis } else if (ix < 0x23d00000) { 527*25c28e83SPiotr Jasiukajtis x *= two768; 528*25c28e83SPiotr Jasiukajtis y *= two768; 529*25c28e83SPiotr Jasiukajtis } 530*25c28e83SPiotr Jasiukajtis y = fabs(y); 531*25c28e83SPiotr Jasiukajtis x = fabs(x); 532*25c28e83SPiotr Jasiukajtis t = y / x; 533*25c28e83SPiotr Jasiukajtis th = t; 534*25c28e83SPiotr Jasiukajtis ((int *) &th)[LOWORD] &= 0xf8000000; 535*25c28e83SPiotr Jasiukajtis xh = x; 536*25c28e83SPiotr Jasiukajtis ((int *) &xh)[LOWORD] &= 0xf8000000; 537*25c28e83SPiotr Jasiukajtis t1 = (x - xh) * t + xh * (t - th); 538*25c28e83SPiotr Jasiukajtis t2 = y - xh * th; 539*25c28e83SPiotr Jasiukajtis w1 = mx_atan(t, &w2); 540*25c28e83SPiotr Jasiukajtis w2 += (t2 - t1) / (x + y * t); 541*25c28e83SPiotr Jasiukajtis if (hx < 0) { 542*25c28e83SPiotr Jasiukajtis t1 = pi - w1; 543*25c28e83SPiotr Jasiukajtis t2 = pi - t1; 544*25c28e83SPiotr Jasiukajtis w2 = (pi_lo - w2) - (w1 - t2); 545*25c28e83SPiotr Jasiukajtis w1 = t1; 546*25c28e83SPiotr Jasiukajtis } 547*25c28e83SPiotr Jasiukajtis *w = (hy >= 0)? w2 : -w2; 548*25c28e83SPiotr Jasiukajtis return ((hy >= 0)? w1 : -w1); 549*25c28e83SPiotr Jasiukajtis } 550*25c28e83SPiotr Jasiukajtis } 551