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_clog_r */
30*25c28e83SPiotr Jasiukajtis #include "complex_wrapper.h"
31*25c28e83SPiotr Jasiukajtis 
32*25c28e83SPiotr Jasiukajtis /* INDENT OFF */
33*25c28e83SPiotr Jasiukajtis /*
34*25c28e83SPiotr Jasiukajtis  * double __k_clog_r(double x, double y, double *e);
35*25c28e83SPiotr Jasiukajtis  *
36*25c28e83SPiotr Jasiukajtis  * Compute real part of complex natural logarithm of x+iy in extra precision
37*25c28e83SPiotr Jasiukajtis  *
38*25c28e83SPiotr Jasiukajtis  * __k_clog_r returns log(hypot(x, y)) with a correction term e.
39*25c28e83SPiotr Jasiukajtis  *
40*25c28e83SPiotr Jasiukajtis  * Accuracy: 70 bits
41*25c28e83SPiotr Jasiukajtis  *
42*25c28e83SPiotr Jasiukajtis  * Method.
43*25c28e83SPiotr Jasiukajtis  * Let Z = x*x + y*y.  Z can be normalized as Z = 2^N * z,  1 <= z < 2.
44*25c28e83SPiotr Jasiukajtis  * We further break down z into 1 + zk + zh + zt, where
45*25c28e83SPiotr Jasiukajtis  *	zk = K*(2^-7) matches z to 7.5 significant bits, 0 <= K <= 2^(-7)-1
46*25c28e83SPiotr Jasiukajtis  *	zh = (z-zk) rounded to 24 bits
47*25c28e83SPiotr Jasiukajtis  *	zt = (z-zk-zh) rounded.
48*25c28e83SPiotr Jasiukajtis  *
49*25c28e83SPiotr Jasiukajtis  *          z - (1+zk)        (zh+zt)
50*25c28e83SPiotr Jasiukajtis  * Let s = ------------ = ---------------, then
51*25c28e83SPiotr Jasiukajtis  *          z + (1+zk)     2(1+zk)+zh+zt
52*25c28e83SPiotr Jasiukajtis  *                                                       z
53*25c28e83SPiotr Jasiukajtis  * log(Z) = N*log2 + log(z) = N*log2 + log(1+zk) + log(------)
54*25c28e83SPiotr Jasiukajtis  *                                                      1+zk
55*25c28e83SPiotr Jasiukajtis  *                                    1+s
56*25c28e83SPiotr Jasiukajtis  *         = N*log2 + log(1+zk) + log(---)
57*25c28e83SPiotr Jasiukajtis  *                                    1-s
58*25c28e83SPiotr Jasiukajtis  *
59*25c28e83SPiotr Jasiukajtis  *                                     1     3    1     5
60*25c28e83SPiotr Jasiukajtis  *        = N*log2 + log(1+zk) + 2s + -- (2s)  + -- (2s)  + ...
61*25c28e83SPiotr Jasiukajtis  *                                    12         80
62*25c28e83SPiotr Jasiukajtis  *
63*25c28e83SPiotr Jasiukajtis  * Note 1. For IEEE double precision,  a seven degree odd polynomial
64*25c28e83SPiotr Jasiukajtis  *		2s + P1*(2s)^3 + P2*(2s)^5 + P3*(2s)^7
65*25c28e83SPiotr Jasiukajtis  *         is generated by a special remez algorithm to
66*25c28e83SPiotr Jasiukajtis  *         approx log((1+s)/(1-s)) accurte to 72 bits.
67*25c28e83SPiotr Jasiukajtis  * Note 2. 2s can be computed accurately as s2h+s2t by
68*25c28e83SPiotr Jasiukajtis  *	   r = 2/((zh+zt)+2(1+zk))
69*25c28e83SPiotr Jasiukajtis  *	   s2 = r*(zh+zt)
70*25c28e83SPiotr Jasiukajtis  *	   s2h = s2 rounded to float;  v = 0.5*s2h;
71*25c28e83SPiotr Jasiukajtis  *	   s2t = r*((((zh-s2h*(1+zk))-v*zh)+zt)-v*zt)
72*25c28e83SPiotr Jasiukajtis  */
73*25c28e83SPiotr Jasiukajtis /* INDENT ON */
74*25c28e83SPiotr Jasiukajtis 
75*25c28e83SPiotr Jasiukajtis static const double
76*25c28e83SPiotr Jasiukajtis zero  = 0.0,
77*25c28e83SPiotr Jasiukajtis half  = 0.5,
78*25c28e83SPiotr Jasiukajtis two   = 2.0,
79*25c28e83SPiotr Jasiukajtis two120 = 1.32922799578491587290e+36,  /* 2^120 */
80*25c28e83SPiotr Jasiukajtis ln2_h  = 6.93147180369123816490e-01,  /* 3fe62e42 fee00000 */
81*25c28e83SPiotr Jasiukajtis ln2_t  = 1.90821492927058770002e-10,  /* 3dea39ef 35793c76 */
82*25c28e83SPiotr Jasiukajtis P1 =  .083333333333333351554108717377986202224765262191125,
83*25c28e83SPiotr Jasiukajtis P2 =  .01249999999819227552330700574633767185896464873834375,
84*25c28e83SPiotr Jasiukajtis P3 =  .0022321938458645656605471559987512516234702284287265625;
85*25c28e83SPiotr Jasiukajtis 
86*25c28e83SPiotr Jasiukajtis /*
87*25c28e83SPiotr Jasiukajtis * T[2k, 2k+1] = log(1+k*2^-7) for k = 0, ..., 2^7 - 1,
88*25c28e83SPiotr Jasiukajtis * with T[2k] * 2^40 is an int
89*25c28e83SPiotr Jasiukajtis */
90*25c28e83SPiotr Jasiukajtis 
91*25c28e83SPiotr Jasiukajtis static const double TBL_log1k[] = {
92*25c28e83SPiotr Jasiukajtis 0.00000000000000000000e+00,  0.00000000000000000000e+00,
93*25c28e83SPiotr Jasiukajtis 7.78214044203195953742e-03,  2.29894100462035112076e-14,
94*25c28e83SPiotr Jasiukajtis 1.55041865355087793432e-02,  4.56474807636434698847e-13,
95*25c28e83SPiotr Jasiukajtis 2.31670592811497044750e-02,  3.84673753843363762372e-13,
96*25c28e83SPiotr Jasiukajtis 3.07716586667083902285e-02,  4.52981425779092882775e-14,
97*25c28e83SPiotr Jasiukajtis 3.83188643018002039753e-02,  3.36395218465265063278e-13,
98*25c28e83SPiotr Jasiukajtis 4.58095360309016541578e-02,  3.92549008891706208826e-13,
99*25c28e83SPiotr Jasiukajtis 5.32445145181554835290e-02,  6.56799336898521766515e-13,
100*25c28e83SPiotr Jasiukajtis 6.06246218158048577607e-02,  6.29984819938331143924e-13,
101*25c28e83SPiotr Jasiukajtis 6.79506619080711971037e-02,  4.36552290856295281946e-13,
102*25c28e83SPiotr Jasiukajtis 7.52234212368421140127e-02,  7.45411685916941618656e-13,
103*25c28e83SPiotr Jasiukajtis 8.24436692109884461388e-02,  8.61451293608781447223e-14,
104*25c28e83SPiotr Jasiukajtis 8.96121586893059429713e-02,  3.81189648692113819551e-13,
105*25c28e83SPiotr Jasiukajtis 9.67296264579999842681e-02,  5.51128027471986918274e-13,
106*25c28e83SPiotr Jasiukajtis 1.03796793680885457434e-01,  7.58107392301637643358e-13,
107*25c28e83SPiotr Jasiukajtis 1.10814366339582193177e-01,  7.07921017612766061755e-13,
108*25c28e83SPiotr Jasiukajtis 1.17783035655520507134e-01,  8.62947404296943765415e-13,
109*25c28e83SPiotr Jasiukajtis 1.24703478500123310369e-01,  8.33925494898414856118e-13,
110*25c28e83SPiotr Jasiukajtis 1.31576357788617315236e-01,  1.01957352237084734958e-13,
111*25c28e83SPiotr Jasiukajtis 1.38402322858382831328e-01,  7.36304357708705134617e-13,
112*25c28e83SPiotr Jasiukajtis 1.45182009843665582594e-01,  8.32314688404647202319e-13,
113*25c28e83SPiotr Jasiukajtis 1.51916042025732167531e-01,  1.09807540998552379211e-13,
114*25c28e83SPiotr Jasiukajtis 1.58605030175749561749e-01,  8.89022343972466269900e-13,
115*25c28e83SPiotr Jasiukajtis 1.65249572894936136436e-01,  3.71026439894104998399e-13,
116*25c28e83SPiotr Jasiukajtis 1.71850256926518341061e-01,  1.40881279371111350341e-13,
117*25c28e83SPiotr Jasiukajtis 1.78407657472234859597e-01,  5.83437522462346671423e-13,
118*25c28e83SPiotr Jasiukajtis 1.84922338493379356805e-01,  6.32635858668445232946e-13,
119*25c28e83SPiotr Jasiukajtis 1.91394852999110298697e-01,  5.19155912393432989209e-13,
120*25c28e83SPiotr Jasiukajtis 1.97825743329303804785e-01,  6.16075577558872326221e-13,
121*25c28e83SPiotr Jasiukajtis 2.04215541428311553318e-01,  3.79338185766902218086e-13,
122*25c28e83SPiotr Jasiukajtis 2.10564769106895255391e-01,  4.54382278998146218219e-13,
123*25c28e83SPiotr Jasiukajtis 2.16873938300523150247e-01,  9.12093724991498410553e-14,
124*25c28e83SPiotr Jasiukajtis 2.23143551314024080057e-01,  1.85675709597960106615e-13,
125*25c28e83SPiotr Jasiukajtis 2.29374101064422575291e-01,  4.23254700234549300166e-13,
126*25c28e83SPiotr Jasiukajtis 2.35566071311950508971e-01,  8.16400106820959292914e-13,
127*25c28e83SPiotr Jasiukajtis 2.41719936886511277407e-01,  6.33890736899755317832e-13,
128*25c28e83SPiotr Jasiukajtis 2.47836163904139539227e-01,  4.41717553713155466566e-13,
129*25c28e83SPiotr Jasiukajtis 2.53915209980732470285e-01,  2.30973852175869394892e-13,
130*25c28e83SPiotr Jasiukajtis 2.59957524436686071567e-01,  2.39995404842117353465e-13,
131*25c28e83SPiotr Jasiukajtis 2.65963548496984003577e-01,  1.53937761744554075681e-13,
132*25c28e83SPiotr Jasiukajtis 2.71933715483100968413e-01,  5.40790418614551497411e-13,
133*25c28e83SPiotr Jasiukajtis 2.77868451003087102436e-01,  3.69203750820800887027e-13,
134*25c28e83SPiotr Jasiukajtis 2.83768173129828937817e-01,  8.15660529536291275782e-13,
135*25c28e83SPiotr Jasiukajtis 2.89633292582948342897e-01,  9.43339818951269030846e-14,
136*25c28e83SPiotr Jasiukajtis 2.95464212893421063200e-01,  4.14813187042585679830e-13,
137*25c28e83SPiotr Jasiukajtis 3.01261330577290209476e-01,  8.71571536970835103739e-13,
138*25c28e83SPiotr Jasiukajtis 3.07025035294827830512e-01,  8.40315630479242455758e-14,
139*25c28e83SPiotr Jasiukajtis 3.12755710003330023028e-01,  5.66865358290073900922e-13,
140*25c28e83SPiotr Jasiukajtis 3.18453731118097493891e-01,  4.37121919574291444278e-13,
141*25c28e83SPiotr Jasiukajtis 3.24119468653407238889e-01,  8.04737201185162774515e-13,
142*25c28e83SPiotr Jasiukajtis 3.29753286371669673827e-01,  7.98307987877335024112e-13,
143*25c28e83SPiotr Jasiukajtis 3.35355541920762334485e-01,  3.75495772572598557174e-13,
144*25c28e83SPiotr Jasiukajtis 3.40926586970454081893e-01,  1.39128412121975659358e-13,
145*25c28e83SPiotr Jasiukajtis 3.46466767346100823488e-01,  1.07757430375726404546e-13,
146*25c28e83SPiotr Jasiukajtis 3.51976423156884266064e-01,  2.93918591876480007730e-13,
147*25c28e83SPiotr Jasiukajtis 3.57455888921322184615e-01,  4.81589611172320539489e-13,
148*25c28e83SPiotr Jasiukajtis 3.62905493689140712377e-01,  2.27740761140395561986e-13,
149*25c28e83SPiotr Jasiukajtis 3.68325561158599157352e-01,  1.08495696229679121506e-13,
150*25c28e83SPiotr Jasiukajtis 3.73716409792905324139e-01,  6.78756682315870616582e-13,
151*25c28e83SPiotr Jasiukajtis 3.79078352934811846353e-01,  1.57612037739694350287e-13,
152*25c28e83SPiotr Jasiukajtis 3.84411698910298582632e-01,  3.34571026954408237380e-14,
153*25c28e83SPiotr Jasiukajtis 3.89716751139530970249e-01,  4.94243121138567024911e-13,
154*25c28e83SPiotr Jasiukajtis 3.94993808240542421117e-01,  3.26556988969071456956e-13,
155*25c28e83SPiotr Jasiukajtis 4.00243164126550254878e-01,  4.62452051668403792833e-13,
156*25c28e83SPiotr Jasiukajtis 4.05465108107819105498e-01,  3.45276479520397708744e-13,
157*25c28e83SPiotr Jasiukajtis 4.10659924984429380856e-01,  8.39005077851830734139e-13,
158*25c28e83SPiotr Jasiukajtis 4.15827895143593195826e-01,  1.17769787513692141889e-13,
159*25c28e83SPiotr Jasiukajtis 4.20969294643327884842e-01,  8.01751287156832458079e-13,
160*25c28e83SPiotr Jasiukajtis 4.26084395310681429692e-01,  2.18633432932159103190e-13,
161*25c28e83SPiotr Jasiukajtis 4.31173464818130014464e-01,  2.41326394913331314894e-13,
162*25c28e83SPiotr Jasiukajtis 4.36236766774527495727e-01,  3.90574622098307022265e-13,
163*25c28e83SPiotr Jasiukajtis 4.41274560804231441580e-01,  6.43787909737320689684e-13,
164*25c28e83SPiotr Jasiukajtis 4.46287102628048160113e-01,  3.71351419195920213229e-13,
165*25c28e83SPiotr Jasiukajtis 4.51274644138720759656e-01,  7.37825488412103968058e-13,
166*25c28e83SPiotr Jasiukajtis 4.56237433480964682531e-01,  6.22911850193784704748e-13,
167*25c28e83SPiotr Jasiukajtis 4.61175715121498797089e-01,  6.71369279138460114513e-13,
168*25c28e83SPiotr Jasiukajtis 4.66089729924533457961e-01,  6.57665976858006147528e-14,
169*25c28e83SPiotr Jasiukajtis 4.70979715218163619284e-01,  6.27393263311115598424e-13,
170*25c28e83SPiotr Jasiukajtis 4.75845904869856894948e-01,  1.07019317621142549209e-13,
171*25c28e83SPiotr Jasiukajtis 4.80688529345570714213e-01,  1.81193463664411114729e-13,
172*25c28e83SPiotr Jasiukajtis 4.85507815781602403149e-01,  9.84046527823262695501e-14,
173*25c28e83SPiotr Jasiukajtis 4.90303988044615834951e-01,  5.78003198945402769376e-13,
174*25c28e83SPiotr Jasiukajtis 4.95077266797125048470e-01,  7.26466128212511528295e-13,
175*25c28e83SPiotr Jasiukajtis 4.99827869555701909121e-01,  7.47420700205478712293e-13,
176*25c28e83SPiotr Jasiukajtis 5.04556010751912253909e-01,  4.83033149495532022300e-13,
177*25c28e83SPiotr Jasiukajtis 5.09261901789614057634e-01,  1.93889170049107088943e-13,
178*25c28e83SPiotr Jasiukajtis 5.13945751101346104406e-01,  8.88212395185718544720e-13,
179*25c28e83SPiotr Jasiukajtis 5.18607764207445143256e-01,  6.00488896640545761201e-13,
180*25c28e83SPiotr Jasiukajtis 5.23248143764249107335e-01,  2.98729182044413286731e-13,
181*25c28e83SPiotr Jasiukajtis 5.27867089620485785417e-01,  3.56599696633478298092e-13,
182*25c28e83SPiotr Jasiukajtis 5.32464798869114019908e-01,  3.57823965912763837621e-13,
183*25c28e83SPiotr Jasiukajtis 5.37041465896436420735e-01,  4.47233831757482468946e-13,
184*25c28e83SPiotr Jasiukajtis 5.41597282432121573947e-01,  6.22797629172251525649e-13,
185*25c28e83SPiotr Jasiukajtis 5.46132437597407260910e-01,  7.28389472720657362987e-13,
186*25c28e83SPiotr Jasiukajtis 5.50647117952394182794e-01,  2.68096466152116723636e-13,
187*25c28e83SPiotr Jasiukajtis 5.55141507539701706264e-01,  7.99886451312335479470e-13,
188*25c28e83SPiotr Jasiukajtis 5.59615787935399566777e-01,  2.31194938380053776320e-14,
189*25c28e83SPiotr Jasiukajtis 5.64070138284478161950e-01,  3.24804121719935740729e-13,
190*25c28e83SPiotr Jasiukajtis 5.68504735351780254859e-01,  8.88457219261483317716e-13,
191*25c28e83SPiotr Jasiukajtis 5.72919753561109246220e-01,  6.76262872317054154667e-13,
192*25c28e83SPiotr Jasiukajtis 5.77315365034337446559e-01,  4.86157758891509033842e-13,
193*25c28e83SPiotr Jasiukajtis 5.81691739634152327199e-01,  4.70155322075549811780e-13,
194*25c28e83SPiotr Jasiukajtis 5.86049045003164792433e-01,  4.13416470738355643357e-13,
195*25c28e83SPiotr Jasiukajtis 5.90387446602107957006e-01,  6.84176364159146659095e-14,
196*25c28e83SPiotr Jasiukajtis 5.94707107746216934174e-01,  4.75855340044306376333e-13,
197*25c28e83SPiotr Jasiukajtis 5.99008189645246602595e-01,  8.36796786747576938145e-13,
198*25c28e83SPiotr Jasiukajtis 6.03290851438032404985e-01,  5.18573553063418286042e-14,
199*25c28e83SPiotr Jasiukajtis 6.07555250224322662689e-01,  2.19132812293400917731e-13,
200*25c28e83SPiotr Jasiukajtis 6.11801541105705837253e-01,  2.87066276408616768331e-13,
201*25c28e83SPiotr Jasiukajtis 6.16029877214714360889e-01,  7.99658758518543977451e-13,
202*25c28e83SPiotr Jasiukajtis 6.20240409751204424538e-01,  6.53104313776336534177e-13,
203*25c28e83SPiotr Jasiukajtis 6.24433288011459808331e-01,  4.33692711555820529733e-13,
204*25c28e83SPiotr Jasiukajtis 6.28608659421843185555e-01,  5.30952189118357790115e-13,
205*25c28e83SPiotr Jasiukajtis 6.32766669570628437214e-01,  4.09392332186786656392e-13,
206*25c28e83SPiotr Jasiukajtis 6.36907462236194987781e-01,  8.74243839148582888557e-13,
207*25c28e83SPiotr Jasiukajtis 6.41031179420679109171e-01,  2.52181884568428814231e-13,
208*25c28e83SPiotr Jasiukajtis 6.45137961372711288277e-01,  8.73413388168702670246e-13,
209*25c28e83SPiotr Jasiukajtis 6.49227946624705509748e-01,  4.04309142530119209805e-13,
210*25c28e83SPiotr Jasiukajtis 6.53301272011958644725e-01,  7.86994033233553225797e-13,
211*25c28e83SPiotr Jasiukajtis 6.57358072708120744210e-01,  2.39285932153437645135e-13,
212*25c28e83SPiotr Jasiukajtis 6.61398482245203922503e-01,  1.61085757539324585156e-13,
213*25c28e83SPiotr Jasiukajtis 6.65422632544505177066e-01,  5.85271884362515112697e-13,
214*25c28e83SPiotr Jasiukajtis 6.69430653942072240170e-01,  5.57027128793880294600e-13,
215*25c28e83SPiotr Jasiukajtis 6.73422675211440946441e-01,  7.25773856816637653180e-13,
216*25c28e83SPiotr Jasiukajtis 6.77398823590920073912e-01,  8.86066898134949155668e-13,
217*25c28e83SPiotr Jasiukajtis 6.81359224807238206267e-01,  6.64862680714687006264e-13,
218*25c28e83SPiotr Jasiukajtis 6.85304003098281100392e-01,  6.38316151706465171657e-13,
219*25c28e83SPiotr Jasiukajtis 6.89233281238557538018e-01,  2.51442307283760746611e-13,
220*25c28e83SPiotr Jasiukajtis };
221*25c28e83SPiotr Jasiukajtis 
222*25c28e83SPiotr Jasiukajtis /*
223*25c28e83SPiotr Jasiukajtis  * Compute N*log2 + log(1+zk+zh+zt) in extra precision
224*25c28e83SPiotr Jasiukajtis  */
k_log_NKz(int N,int K,double zh,double * zt)225*25c28e83SPiotr Jasiukajtis static double k_log_NKz(int N, int K, double zh, double *zt)
226*25c28e83SPiotr Jasiukajtis {
227*25c28e83SPiotr Jasiukajtis 	double y, r, w, s2, s2h, s2t, t, zk, v, P;
228*25c28e83SPiotr Jasiukajtis 
229*25c28e83SPiotr Jasiukajtis 	((int *)&zk)[HIWORD] = 0x3ff00000 + (K << 13);
230*25c28e83SPiotr Jasiukajtis 	((int *)&zk)[LOWORD] = 0;
231*25c28e83SPiotr Jasiukajtis 	t  = zh + (*zt);
232*25c28e83SPiotr Jasiukajtis 	r = two / (t + two * zk);
233*25c28e83SPiotr Jasiukajtis 	s2h = s2 = r * t;
234*25c28e83SPiotr Jasiukajtis 	((int *)&s2h)[LOWORD] &= 0xe0000000;
235*25c28e83SPiotr Jasiukajtis 	v = half * s2h;
236*25c28e83SPiotr Jasiukajtis 	w = s2 * s2;
237*25c28e83SPiotr Jasiukajtis 	s2t = r * ((((zh - s2h * zk) - v * zh) + (*zt)) - v * (*zt));
238*25c28e83SPiotr Jasiukajtis 	P = s2t + (w * s2) * ((P1 + w * P2) + (w * w) * P3);
239*25c28e83SPiotr Jasiukajtis 	P += N * ln2_t + TBL_log1k[K + K + 1];
240*25c28e83SPiotr Jasiukajtis 	t = N*ln2_h + TBL_log1k[K+K];
241*25c28e83SPiotr Jasiukajtis 	y = t + (P + s2h);
242*25c28e83SPiotr Jasiukajtis 	P -= ((y - t) - s2h);
243*25c28e83SPiotr Jasiukajtis 	*zt = P;
244*25c28e83SPiotr Jasiukajtis 	return (y);
245*25c28e83SPiotr Jasiukajtis }
246*25c28e83SPiotr Jasiukajtis 
247*25c28e83SPiotr Jasiukajtis double
__k_clog_r(double x,double y,double * er)248*25c28e83SPiotr Jasiukajtis __k_clog_r(double x, double y, double *er)
249*25c28e83SPiotr Jasiukajtis {
250*25c28e83SPiotr Jasiukajtis 	double t1, t2, t3, t4, tk, z, wh, w, zh, zk;
251*25c28e83SPiotr Jasiukajtis 	int n, k, ix, iy, iz, nx, ny, nz, i, j;
252*25c28e83SPiotr Jasiukajtis 	unsigned lx, ly;
253*25c28e83SPiotr Jasiukajtis 
254*25c28e83SPiotr Jasiukajtis 	ix = (((int *)&x)[HIWORD]) & ~0x80000000;
255*25c28e83SPiotr Jasiukajtis 	lx = ((unsigned *)&x)[LOWORD];
256*25c28e83SPiotr Jasiukajtis 	iy = (((int *)&y)[HIWORD]) & ~0x80000000;
257*25c28e83SPiotr Jasiukajtis 	ly = ((unsigned *)&y)[LOWORD];
258*25c28e83SPiotr Jasiukajtis 	y = fabs(y); x = fabs(x);
259*25c28e83SPiotr Jasiukajtis 	if (ix < iy || (ix == iy && lx < ly)) {		/* force x >= y */
260*25c28e83SPiotr Jasiukajtis 		tk = x;  x = y;   y = tk;
261*25c28e83SPiotr Jasiukajtis 		n = ix, ix = iy; iy = n;
262*25c28e83SPiotr Jasiukajtis 		n = lx, lx = ly; ly = n;
263*25c28e83SPiotr Jasiukajtis 	}
264*25c28e83SPiotr Jasiukajtis 	*er = zero;
265*25c28e83SPiotr Jasiukajtis 	nx = ix >> 20; ny = iy >> 20;
266*25c28e83SPiotr Jasiukajtis 	if (nx >= 0x7ff) {   	/* x or y is Inf or NaN */
267*25c28e83SPiotr Jasiukajtis 		if (ISINF(ix, lx))
268*25c28e83SPiotr Jasiukajtis 			return (x);
269*25c28e83SPiotr Jasiukajtis 		else if (ISINF(iy, ly))
270*25c28e83SPiotr Jasiukajtis 			return (y);
271*25c28e83SPiotr Jasiukajtis 		else
272*25c28e83SPiotr Jasiukajtis 			return (x+y);
273*25c28e83SPiotr Jasiukajtis 	}
274*25c28e83SPiotr Jasiukajtis /*
275*25c28e83SPiotr Jasiukajtis  * for tiny y (double y < 2^-35, extended y < 2^-46, quad y < 2^-70):
276*25c28e83SPiotr Jasiukajtis  * 	log(sqrt(1+y^2)) = (y^2)/2 - (y^4)/8 + ... ~= (y^2)/2
277*25c28e83SPiotr Jasiukajtis  */
278*25c28e83SPiotr Jasiukajtis 	if ((((ix - 0x3ff00000) | lx) == 0) && ny < (0x3ff - 35))  {
279*25c28e83SPiotr Jasiukajtis 		t2 = y * y;
280*25c28e83SPiotr Jasiukajtis 		if (ny >= 565) {	/* compute er = tail of t2 */
281*25c28e83SPiotr Jasiukajtis 			((int *)&wh)[HIWORD] =  iy;
282*25c28e83SPiotr Jasiukajtis 			((unsigned *)&wh)[LOWORD] = ly & 0xf8000000;
283*25c28e83SPiotr Jasiukajtis 			*er = half * ((y - wh) * (y + wh) - (t2 - wh * wh));
284*25c28e83SPiotr Jasiukajtis 		}
285*25c28e83SPiotr Jasiukajtis 		return (half * t2);
286*25c28e83SPiotr Jasiukajtis 	}
287*25c28e83SPiotr Jasiukajtis /*
288*25c28e83SPiotr Jasiukajtis  * x or y is subnormal or zero
289*25c28e83SPiotr Jasiukajtis  */
290*25c28e83SPiotr Jasiukajtis 	if (nx == 0) {
291*25c28e83SPiotr Jasiukajtis 		if ((ix | lx) == 0)
292*25c28e83SPiotr Jasiukajtis 			return (-1.0 / x);
293*25c28e83SPiotr Jasiukajtis 		else {
294*25c28e83SPiotr Jasiukajtis 			x *= two120;
295*25c28e83SPiotr Jasiukajtis 			y *= two120;
296*25c28e83SPiotr Jasiukajtis 			ix = ((int *)&x)[HIWORD];
297*25c28e83SPiotr Jasiukajtis 			lx = ((unsigned *)&x)[LOWORD];
298*25c28e83SPiotr Jasiukajtis 			iy = ((int *)&y)[HIWORD];
299*25c28e83SPiotr Jasiukajtis 			ly = ((unsigned *)&y)[LOWORD];
300*25c28e83SPiotr Jasiukajtis 			nx = (ix >> 20) - 120;
301*25c28e83SPiotr Jasiukajtis 			ny = (iy >> 20) - 120;
302*25c28e83SPiotr Jasiukajtis 			/* guard subnormal flush to 0 */
303*25c28e83SPiotr Jasiukajtis 			if ((ix | lx) == 0)
304*25c28e83SPiotr Jasiukajtis 				return (-1.0 / x);
305*25c28e83SPiotr Jasiukajtis 		}
306*25c28e83SPiotr Jasiukajtis 	} else if (ny == 0) {	/* y subnormal, scale it */
307*25c28e83SPiotr Jasiukajtis 		y *= two120;
308*25c28e83SPiotr Jasiukajtis 		iy = ((int *)&y)[HIWORD];
309*25c28e83SPiotr Jasiukajtis 		ly = ((unsigned *)&y)[LOWORD];
310*25c28e83SPiotr Jasiukajtis 		ny = (iy >> 20) - 120;
311*25c28e83SPiotr Jasiukajtis 	}
312*25c28e83SPiotr Jasiukajtis 	n = nx - ny;
313*25c28e83SPiotr Jasiukajtis /*
314*25c28e83SPiotr Jasiukajtis  * return log(x) when y is zero or x >> y so that
315*25c28e83SPiotr Jasiukajtis  * log(x) ~ log(sqrt(x*x+y*y)) to 27 extra bits
316*25c28e83SPiotr Jasiukajtis  * (n > 62 for double, 78 for i386 extended, 122 for quad)
317*25c28e83SPiotr Jasiukajtis  */
318*25c28e83SPiotr Jasiukajtis 	if (n > 62 || (iy | ly) == 0) {
319*25c28e83SPiotr Jasiukajtis 		i = (0x000fffff & ix) | 0x3ff00000;	/* normalize x */
320*25c28e83SPiotr Jasiukajtis 		((int *)&x)[HIWORD] = i;
321*25c28e83SPiotr Jasiukajtis 		i += 0x1000;
322*25c28e83SPiotr Jasiukajtis 		((int *)&zk)[HIWORD] = i & 0xffffe000;
323*25c28e83SPiotr Jasiukajtis 		((int *)&zk)[LOWORD] = 0;  /* zk matches 7.5 bits of x */
324*25c28e83SPiotr Jasiukajtis 		z = x - zk;
325*25c28e83SPiotr Jasiukajtis 		zh = (double)((float)z);
326*25c28e83SPiotr Jasiukajtis 		i >>= 13;
327*25c28e83SPiotr Jasiukajtis 		k = i & 0x7f;	/* index of zk */
328*25c28e83SPiotr Jasiukajtis 		n = nx - 0x3ff;
329*25c28e83SPiotr Jasiukajtis 		*er = z - zh;
330*25c28e83SPiotr Jasiukajtis 		if (i >> 17) {	/* if zk = 2.0, adjust scaling */
331*25c28e83SPiotr Jasiukajtis 			n += 1;
332*25c28e83SPiotr Jasiukajtis 			zh *= 0.5;  *er *= 0.5;
333*25c28e83SPiotr Jasiukajtis 		}
334*25c28e83SPiotr Jasiukajtis 		w = k_log_NKz(n, k, zh, er);
335*25c28e83SPiotr Jasiukajtis 	} else {
336*25c28e83SPiotr Jasiukajtis /*
337*25c28e83SPiotr Jasiukajtis  * compute z = x*x + y*y
338*25c28e83SPiotr Jasiukajtis  */
339*25c28e83SPiotr Jasiukajtis 		ix = (ix & 0xfffff) | 0x3ff00000;
340*25c28e83SPiotr Jasiukajtis 		iy = (iy & 0xfffff) | (0x3ff00000 - (n << 20));
341*25c28e83SPiotr Jasiukajtis 		((int *)&x)[HIWORD] = ix; ((int *)&y)[HIWORD] = iy;
342*25c28e83SPiotr Jasiukajtis 		t1 = x * x; t2 = y * y;
343*25c28e83SPiotr Jasiukajtis 		j = ((lx >> 26) + 1) >> 1;
344*25c28e83SPiotr Jasiukajtis 		((int *)&wh)[HIWORD] = ix + (j >> 5);
345*25c28e83SPiotr Jasiukajtis 		((unsigned *)&wh)[LOWORD] = (j << 27);
346*25c28e83SPiotr Jasiukajtis 		z = t1+t2;
347*25c28e83SPiotr Jasiukajtis /*
348*25c28e83SPiotr Jasiukajtis  * higher precision simulation x*x = t1 + t3, y*y = t2 + t4
349*25c28e83SPiotr Jasiukajtis  */
350*25c28e83SPiotr Jasiukajtis 		tk = wh - x;
351*25c28e83SPiotr Jasiukajtis 		t3 = tk * tk - (two * wh * tk - (wh * wh - t1));
352*25c28e83SPiotr Jasiukajtis 		j = ((ly >> 26) + 1) >> 1;
353*25c28e83SPiotr Jasiukajtis 		((int *)&wh)[HIWORD] = iy + (j >> 5);
354*25c28e83SPiotr Jasiukajtis 		((unsigned *)&wh)[LOWORD] = (j << 27);
355*25c28e83SPiotr Jasiukajtis 		tk = wh - y;
356*25c28e83SPiotr Jasiukajtis 		t4 = tk * tk - (two * wh * tk - (wh * wh - t2));
357*25c28e83SPiotr Jasiukajtis /*
358*25c28e83SPiotr Jasiukajtis  * find zk matches z to 7.5 bits
359*25c28e83SPiotr Jasiukajtis  */
360*25c28e83SPiotr Jasiukajtis 		nx -= 0x3ff;
361*25c28e83SPiotr Jasiukajtis 		iz = ((int *)&z)[HIWORD] + 0x1000;
362*25c28e83SPiotr Jasiukajtis 		k = (iz >> 13) & 0x7f;
363*25c28e83SPiotr Jasiukajtis 		nz = (iz >> 20) - 0x3ff;
364*25c28e83SPiotr Jasiukajtis 		((int *)&zk)[HIWORD] = iz & 0xffffe000;
365*25c28e83SPiotr Jasiukajtis 		((int *)&zk)[LOWORD] = 0;
366*25c28e83SPiotr Jasiukajtis /*
367*25c28e83SPiotr Jasiukajtis  * order t1,t2,t3,t4 according to their size
368*25c28e83SPiotr Jasiukajtis  */
369*25c28e83SPiotr Jasiukajtis 		if (t2 >= fabs(t3)) {
370*25c28e83SPiotr Jasiukajtis 			if (fabs(t3) < fabs(t4)) {
371*25c28e83SPiotr Jasiukajtis 				wh = t3;  t3 = t4; t4 = wh;
372*25c28e83SPiotr Jasiukajtis 			}
373*25c28e83SPiotr Jasiukajtis 		} else {
374*25c28e83SPiotr Jasiukajtis 			wh = t2; t2 = t3; t3 = wh;
375*25c28e83SPiotr Jasiukajtis 		}
376*25c28e83SPiotr Jasiukajtis /*
377*25c28e83SPiotr Jasiukajtis  * higher precision simulation: x * x + y * y = t1 + t2 + t3 + t4
378*25c28e83SPiotr Jasiukajtis  * = zk (7 bits) + zh (24 bits) + *er (tail) and call k_log_NKz
379*25c28e83SPiotr Jasiukajtis  */
380*25c28e83SPiotr Jasiukajtis 		tk = t1 - zk;
381*25c28e83SPiotr Jasiukajtis 		zh = ((tk + t2) + t3) + t4;
382*25c28e83SPiotr Jasiukajtis 		((int *)&zh)[LOWORD] &= 0xe0000000;
383*25c28e83SPiotr Jasiukajtis 		w = fabs(zh);
384*25c28e83SPiotr Jasiukajtis 		if (w >= fabs(t2))
385*25c28e83SPiotr Jasiukajtis 			*er = (((tk - zh) + t2) + t3) + t4;
386*25c28e83SPiotr Jasiukajtis 		else {
387*25c28e83SPiotr Jasiukajtis 			if (n == 0) {
388*25c28e83SPiotr Jasiukajtis 				wh = half * zk;
389*25c28e83SPiotr Jasiukajtis 				wh = (t1 - wh) - (wh - t2);
390*25c28e83SPiotr Jasiukajtis 			} else
391*25c28e83SPiotr Jasiukajtis 				wh = tk + t2;
392*25c28e83SPiotr Jasiukajtis 			if (w >= fabs(t3))
393*25c28e83SPiotr Jasiukajtis 				*er = ((wh - zh) + t3) + t4;
394*25c28e83SPiotr Jasiukajtis 			else {
395*25c28e83SPiotr Jasiukajtis 				z = t3;
396*25c28e83SPiotr Jasiukajtis 				t3 += t4;
397*25c28e83SPiotr Jasiukajtis 				t4 -= t3 - z;
398*25c28e83SPiotr Jasiukajtis 				if (w >= fabs(t3))
399*25c28e83SPiotr Jasiukajtis 					*er = ((wh - zh) + t3) + t4;
400*25c28e83SPiotr Jasiukajtis 				else
401*25c28e83SPiotr Jasiukajtis 					*er = ((wh + t3) - zh) + t4;
402*25c28e83SPiotr Jasiukajtis 			}
403*25c28e83SPiotr Jasiukajtis 		}
404*25c28e83SPiotr Jasiukajtis 		if (nz == 3) {zh *= 0.125; *er *= 0.125; }
405*25c28e83SPiotr Jasiukajtis 		if (nz == 2) {zh *= 0.25; *er *= 0.25; }
406*25c28e83SPiotr Jasiukajtis 		if (nz == 1) {zh *= half; *er *= half; }
407*25c28e83SPiotr Jasiukajtis 		nz += nx + nx;
408*25c28e83SPiotr Jasiukajtis 		w = half * k_log_NKz(nz, k, zh, er);
409*25c28e83SPiotr Jasiukajtis 		*er *= half;
410*25c28e83SPiotr Jasiukajtis 	}
411*25c28e83SPiotr Jasiukajtis 	return (w);
412*25c28e83SPiotr Jasiukajtis }
413