134126Sbostic /* 256955Sbostic * Copyright (c) 1992 Regents of the University of California. 334126Sbostic * All rights reserved. 434126Sbostic * 542657Sbostic * %sccs.include.redist.c% 624601Szliu */ 724601Szliu 824601Szliu #ifndef lint 9*57442Sbostic static char sccsid[] = "@(#)log.c 5.10 (Berkeley) 01/10/93"; 1034126Sbostic #endif /* not lint */ 1124601Szliu 1256955Sbostic #include <math.h> 1356955Sbostic #include <errno.h> 1456955Sbostic 1557158Smcilroy #include "mathimpl.h" 1656955Sbostic 1756955Sbostic /* Table-driven natural logarithm. 1824601Szliu * 1956955Sbostic * This code was derived, with minor modifications, from: 2056955Sbostic * Peter Tang, "Table-Driven Implementation of the 2156955Sbostic * Logarithm in IEEE Floating-Point arithmetic." ACM Trans. 2256955Sbostic * Math Software, vol 16. no 4, pp 378-400, Dec 1990). 2324601Szliu * 2456955Sbostic * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256, 2556955Sbostic * where F = j/128 for j an integer in [0, 128]. 2624601Szliu * 2756955Sbostic * log(2^m) = log2_hi*m + log2_tail*m 2856955Sbostic * since m is an integer, the dominant term is exact. 2956955Sbostic * m has at most 10 digits (for subnormal numbers), 3056955Sbostic * and log2_hi has 11 trailing zero bits. 3124601Szliu * 3256955Sbostic * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h 3356955Sbostic * logF_hi[] + 512 is exact. 3424601Szliu * 3556955Sbostic * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ... 3656955Sbostic * the leading term is calculated to extra precision in two 3756955Sbostic * parts, the larger of which adds exactly to the dominant 3856955Sbostic * m and F terms. 3956955Sbostic * There are two cases: 4056955Sbostic * 1. when m, j are non-zero (m | j), use absolute 4156955Sbostic * precision for the leading term. 4256955Sbostic * 2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1). 4356955Sbostic * In this case, use a relative precision of 24 bits. 4456955Sbostic * (This is done differently in the original paper) 4524601Szliu * 4624601Szliu * Special cases: 4756955Sbostic * 0 return signalling -Inf 4856955Sbostic * neg return signalling NaN 4956955Sbostic * +Inf return +Inf 5056955Sbostic */ 5124601Szliu 5256955Sbostic #if defined(vax) || defined(tahoe) 5357156Smcilroy #define _IEEE 0 5457156Smcilroy #define TRUNC(x) x = (double) (float) (x) 5556955Sbostic #else 56*57442Sbostic #define _IEEE 1 5757156Smcilroy #define endian (((*(int *) &one)) ? 1 : 0) 5857156Smcilroy #define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000 5957156Smcilroy #define infnan(x) 0.0 6056955Sbostic #endif 6124601Szliu 62*57442Sbostic #define N 128 63*57442Sbostic 64*57442Sbostic /* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128. 65*57442Sbostic * Used for generation of extend precision logarithms. 66*57442Sbostic * The constant 35184372088832 is 2^45, so the divide is exact. 67*57442Sbostic * It ensures correct reading of logF_head, even for inaccurate 68*57442Sbostic * decimal-to-binary conversion routines. (Everybody gets the 69*57442Sbostic * right answer for integers less than 2^53.) 70*57442Sbostic * Values for log(F) were generated using error < 10^-57 absolute 71*57442Sbostic * with the bc -l package. 72*57442Sbostic */ 73*57442Sbostic double A1 = .08333333333333178827; 74*57442Sbostic double A2 = .01250000000377174923; 75*57442Sbostic double A3 = .002232139987919447809; 76*57442Sbostic double A4 = .0004348877777076145742; 77*57442Sbostic 78*57442Sbostic double logF_head[N+1] = { 79*57442Sbostic 0., 80*57442Sbostic .007782140442060381246, 81*57442Sbostic .015504186535963526694, 82*57442Sbostic .023167059281547608406, 83*57442Sbostic .030771658666765233647, 84*57442Sbostic .038318864302141264488, 85*57442Sbostic .045809536031242714670, 86*57442Sbostic .053244514518837604555, 87*57442Sbostic .060624621816486978786, 88*57442Sbostic .067950661908525944454, 89*57442Sbostic .075223421237524235039, 90*57442Sbostic .082443669210988446138, 91*57442Sbostic .089612158689760690322, 92*57442Sbostic .096729626458454731618, 93*57442Sbostic .103796793681567578460, 94*57442Sbostic .110814366340264314203, 95*57442Sbostic .117783035656430001836, 96*57442Sbostic .124703478501032805070, 97*57442Sbostic .131576357788617315236, 98*57442Sbostic .138402322859292326029, 99*57442Sbostic .145182009844575077295, 100*57442Sbostic .151916042025732167530, 101*57442Sbostic .158605030176659056451, 102*57442Sbostic .165249572895390883786, 103*57442Sbostic .171850256926518341060, 104*57442Sbostic .178407657472689606947, 105*57442Sbostic .184922338493834104156, 106*57442Sbostic .191394852999565046047, 107*57442Sbostic .197825743329758552135, 108*57442Sbostic .204215541428766300668, 109*57442Sbostic .210564769107350002741, 110*57442Sbostic .216873938300523150246, 111*57442Sbostic .223143551314024080056, 112*57442Sbostic .229374101064877322642, 113*57442Sbostic .235566071312860003672, 114*57442Sbostic .241719936886966024758, 115*57442Sbostic .247836163904594286577, 116*57442Sbostic .253915209980732470285, 117*57442Sbostic .259957524436686071567, 118*57442Sbostic .265963548496984003577, 119*57442Sbostic .271933715484010463114, 120*57442Sbostic .277868451003087102435, 121*57442Sbostic .283768173130738432519, 122*57442Sbostic .289633292582948342896, 123*57442Sbostic .295464212893421063199, 124*57442Sbostic .301261330578199704177, 125*57442Sbostic .307025035294827830512, 126*57442Sbostic .312755710004239517729, 127*57442Sbostic .318453731118097493890, 128*57442Sbostic .324119468654316733591, 129*57442Sbostic .329753286372579168528, 130*57442Sbostic .335355541920762334484, 131*57442Sbostic .340926586970454081892, 132*57442Sbostic .346466767346100823488, 133*57442Sbostic .351976423156884266063, 134*57442Sbostic .357455888922231679316, 135*57442Sbostic .362905493689140712376, 136*57442Sbostic .368325561158599157352, 137*57442Sbostic .373716409793814818840, 138*57442Sbostic .379078352934811846353, 139*57442Sbostic .384411698910298582632, 140*57442Sbostic .389716751140440464951, 141*57442Sbostic .394993808240542421117, 142*57442Sbostic .400243164127459749579, 143*57442Sbostic .405465108107819105498, 144*57442Sbostic .410659924985338875558, 145*57442Sbostic .415827895143593195825, 146*57442Sbostic .420969294644237379543, 147*57442Sbostic .426084395310681429691, 148*57442Sbostic .431173464818130014464, 149*57442Sbostic .436236766774527495726, 150*57442Sbostic .441274560805140936281, 151*57442Sbostic .446287102628048160113, 152*57442Sbostic .451274644139630254358, 153*57442Sbostic .456237433481874177232, 154*57442Sbostic .461175715122408291790, 155*57442Sbostic .466089729924533457960, 156*57442Sbostic .470979715219073113985, 157*57442Sbostic .475845904869856894947, 158*57442Sbostic .480688529345570714212, 159*57442Sbostic .485507815781602403149, 160*57442Sbostic .490303988045525329653, 161*57442Sbostic .495077266798034543171, 162*57442Sbostic .499827869556611403822, 163*57442Sbostic .504556010751912253908, 164*57442Sbostic .509261901790523552335, 165*57442Sbostic .513945751101346104405, 166*57442Sbostic .518607764208354637958, 167*57442Sbostic .523248143765158602036, 168*57442Sbostic .527867089620485785417, 169*57442Sbostic .532464798869114019908, 170*57442Sbostic .537041465897345915436, 171*57442Sbostic .541597282432121573947, 172*57442Sbostic .546132437597407260909, 173*57442Sbostic .550647117952394182793, 174*57442Sbostic .555141507540611200965, 175*57442Sbostic .559615787935399566777, 176*57442Sbostic .564070138285387656651, 177*57442Sbostic .568504735352689749561, 178*57442Sbostic .572919753562018740922, 179*57442Sbostic .577315365035246941260, 180*57442Sbostic .581691739635061821900, 181*57442Sbostic .586049045003164792433, 182*57442Sbostic .590387446602107957005, 183*57442Sbostic .594707107746216934174, 184*57442Sbostic .599008189645246602594, 185*57442Sbostic .603290851438941899687, 186*57442Sbostic .607555250224322662688, 187*57442Sbostic .611801541106615331955, 188*57442Sbostic .616029877215623855590, 189*57442Sbostic .620240409751204424537, 190*57442Sbostic .624433288012369303032, 191*57442Sbostic .628608659422752680256, 192*57442Sbostic .632766669570628437213, 193*57442Sbostic .636907462236194987781, 194*57442Sbostic .641031179420679109171, 195*57442Sbostic .645137961373620782978, 196*57442Sbostic .649227946625615004450, 197*57442Sbostic .653301272011958644725, 198*57442Sbostic .657358072709030238911, 199*57442Sbostic .661398482245203922502, 200*57442Sbostic .665422632544505177065, 201*57442Sbostic .669430653942981734871, 202*57442Sbostic .673422675212350441142, 203*57442Sbostic .677398823590920073911, 204*57442Sbostic .681359224807238206267, 205*57442Sbostic .685304003098281100392, 206*57442Sbostic .689233281238557538017, 207*57442Sbostic .693147180560117703862 208*57442Sbostic }; 209*57442Sbostic 210*57442Sbostic double logF_tail[N+1] = { 211*57442Sbostic 0., 212*57442Sbostic -.00000000000000543229938420049, 213*57442Sbostic .00000000000000172745674997061, 214*57442Sbostic -.00000000000001323017818229233, 215*57442Sbostic -.00000000000001154527628289872, 216*57442Sbostic -.00000000000000466529469958300, 217*57442Sbostic .00000000000005148849572685810, 218*57442Sbostic -.00000000000002532168943117445, 219*57442Sbostic -.00000000000005213620639136504, 220*57442Sbostic -.00000000000001819506003016881, 221*57442Sbostic .00000000000006329065958724544, 222*57442Sbostic .00000000000008614512936087814, 223*57442Sbostic -.00000000000007355770219435028, 224*57442Sbostic .00000000000009638067658552277, 225*57442Sbostic .00000000000007598636597194141, 226*57442Sbostic .00000000000002579999128306990, 227*57442Sbostic -.00000000000004654729747598444, 228*57442Sbostic -.00000000000007556920687451336, 229*57442Sbostic .00000000000010195735223708472, 230*57442Sbostic -.00000000000017319034406422306, 231*57442Sbostic -.00000000000007718001336828098, 232*57442Sbostic .00000000000010980754099855238, 233*57442Sbostic -.00000000000002047235780046195, 234*57442Sbostic -.00000000000008372091099235912, 235*57442Sbostic .00000000000014088127937111135, 236*57442Sbostic .00000000000012869017157588257, 237*57442Sbostic .00000000000017788850778198106, 238*57442Sbostic .00000000000006440856150696891, 239*57442Sbostic .00000000000016132822667240822, 240*57442Sbostic -.00000000000007540916511956188, 241*57442Sbostic -.00000000000000036507188831790, 242*57442Sbostic .00000000000009120937249914984, 243*57442Sbostic .00000000000018567570959796010, 244*57442Sbostic -.00000000000003149265065191483, 245*57442Sbostic -.00000000000009309459495196889, 246*57442Sbostic .00000000000017914338601329117, 247*57442Sbostic -.00000000000001302979717330866, 248*57442Sbostic .00000000000023097385217586939, 249*57442Sbostic .00000000000023999540484211737, 250*57442Sbostic .00000000000015393776174455408, 251*57442Sbostic -.00000000000036870428315837678, 252*57442Sbostic .00000000000036920375082080089, 253*57442Sbostic -.00000000000009383417223663699, 254*57442Sbostic .00000000000009433398189512690, 255*57442Sbostic .00000000000041481318704258568, 256*57442Sbostic -.00000000000003792316480209314, 257*57442Sbostic .00000000000008403156304792424, 258*57442Sbostic -.00000000000034262934348285429, 259*57442Sbostic .00000000000043712191957429145, 260*57442Sbostic -.00000000000010475750058776541, 261*57442Sbostic -.00000000000011118671389559323, 262*57442Sbostic .00000000000037549577257259853, 263*57442Sbostic .00000000000013912841212197565, 264*57442Sbostic .00000000000010775743037572640, 265*57442Sbostic .00000000000029391859187648000, 266*57442Sbostic -.00000000000042790509060060774, 267*57442Sbostic .00000000000022774076114039555, 268*57442Sbostic .00000000000010849569622967912, 269*57442Sbostic -.00000000000023073801945705758, 270*57442Sbostic .00000000000015761203773969435, 271*57442Sbostic .00000000000003345710269544082, 272*57442Sbostic -.00000000000041525158063436123, 273*57442Sbostic .00000000000032655698896907146, 274*57442Sbostic -.00000000000044704265010452446, 275*57442Sbostic .00000000000034527647952039772, 276*57442Sbostic -.00000000000007048962392109746, 277*57442Sbostic .00000000000011776978751369214, 278*57442Sbostic -.00000000000010774341461609578, 279*57442Sbostic .00000000000021863343293215910, 280*57442Sbostic .00000000000024132639491333131, 281*57442Sbostic .00000000000039057462209830700, 282*57442Sbostic -.00000000000026570679203560751, 283*57442Sbostic .00000000000037135141919592021, 284*57442Sbostic -.00000000000017166921336082431, 285*57442Sbostic -.00000000000028658285157914353, 286*57442Sbostic -.00000000000023812542263446809, 287*57442Sbostic .00000000000006576659768580062, 288*57442Sbostic -.00000000000028210143846181267, 289*57442Sbostic .00000000000010701931762114254, 290*57442Sbostic .00000000000018119346366441110, 291*57442Sbostic .00000000000009840465278232627, 292*57442Sbostic -.00000000000033149150282752542, 293*57442Sbostic -.00000000000018302857356041668, 294*57442Sbostic -.00000000000016207400156744949, 295*57442Sbostic .00000000000048303314949553201, 296*57442Sbostic -.00000000000071560553172382115, 297*57442Sbostic .00000000000088821239518571855, 298*57442Sbostic -.00000000000030900580513238244, 299*57442Sbostic -.00000000000061076551972851496, 300*57442Sbostic .00000000000035659969663347830, 301*57442Sbostic .00000000000035782396591276383, 302*57442Sbostic -.00000000000046226087001544578, 303*57442Sbostic .00000000000062279762917225156, 304*57442Sbostic .00000000000072838947272065741, 305*57442Sbostic .00000000000026809646615211673, 306*57442Sbostic -.00000000000010960825046059278, 307*57442Sbostic .00000000000002311949383800537, 308*57442Sbostic -.00000000000058469058005299247, 309*57442Sbostic -.00000000000002103748251144494, 310*57442Sbostic -.00000000000023323182945587408, 311*57442Sbostic -.00000000000042333694288141916, 312*57442Sbostic -.00000000000043933937969737844, 313*57442Sbostic .00000000000041341647073835565, 314*57442Sbostic .00000000000006841763641591466, 315*57442Sbostic .00000000000047585534004430641, 316*57442Sbostic .00000000000083679678674757695, 317*57442Sbostic -.00000000000085763734646658640, 318*57442Sbostic .00000000000021913281229340092, 319*57442Sbostic -.00000000000062242842536431148, 320*57442Sbostic -.00000000000010983594325438430, 321*57442Sbostic .00000000000065310431377633651, 322*57442Sbostic -.00000000000047580199021710769, 323*57442Sbostic -.00000000000037854251265457040, 324*57442Sbostic .00000000000040939233218678664, 325*57442Sbostic .00000000000087424383914858291, 326*57442Sbostic .00000000000025218188456842882, 327*57442Sbostic -.00000000000003608131360422557, 328*57442Sbostic -.00000000000050518555924280902, 329*57442Sbostic .00000000000078699403323355317, 330*57442Sbostic -.00000000000067020876961949060, 331*57442Sbostic .00000000000016108575753932458, 332*57442Sbostic .00000000000058527188436251509, 333*57442Sbostic -.00000000000035246757297904791, 334*57442Sbostic -.00000000000018372084495629058, 335*57442Sbostic .00000000000088606689813494916, 336*57442Sbostic .00000000000066486268071468700, 337*57442Sbostic .00000000000063831615170646519, 338*57442Sbostic .00000000000025144230728376072, 339*57442Sbostic -.00000000000017239444525614834 340*57442Sbostic }; 341*57442Sbostic 34256955Sbostic double 34356955Sbostic #ifdef _ANSI_SOURCE 34456955Sbostic log(double x) 34556955Sbostic #else 34656955Sbostic log(x) double x; 34756955Sbostic #endif 34856955Sbostic { 34956955Sbostic int m, j; 35056955Sbostic double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0; 35156955Sbostic double logb(), ldexp(); 35256955Sbostic volatile double u1; 35335679Sbostic 35456955Sbostic /* Catch special cases */ 35556955Sbostic if (x <= 0) 35656955Sbostic if (_IEEE && x == zero) /* log(0) = -Inf */ 35756955Sbostic return (-one/zero); 35856955Sbostic else if (_IEEE) /* log(neg) = NaN */ 35956955Sbostic return (zero/zero); 36056955Sbostic else if (x == zero) /* NOT REACHED IF _IEEE */ 36156955Sbostic return (infnan(-ERANGE)); 36256955Sbostic else 36356955Sbostic return (infnan(EDOM)); 36456955Sbostic else if (!finite(x)) 36556955Sbostic if (_IEEE) /* x = NaN, Inf */ 36656955Sbostic return (x+x); 36756955Sbostic else 36856955Sbostic return (infnan(ERANGE)); 36956955Sbostic 37056955Sbostic /* Argument reduction: 1 <= g < 2; x/2^m = g; */ 37156955Sbostic /* y = F*(1 + f/F) for |f| <= 2^-8 */ 37235679Sbostic 37356955Sbostic m = logb(x); 37456955Sbostic g = ldexp(x, -m); 37556955Sbostic if (_IEEE && m == -1022) { 37656955Sbostic j = logb(g), m += j; 37756955Sbostic g = ldexp(g, -j); 37856955Sbostic } 37956955Sbostic j = N*(g-1) + .5; 38056955Sbostic F = (1.0/N) * j + 1; /* F*128 is an integer in [128, 512] */ 38156955Sbostic f = g - F; 38235679Sbostic 38356955Sbostic /* Approximate expansion for log(1+f/F) ~= u + q */ 38456955Sbostic g = 1/(2*F+f); 38556955Sbostic u = 2*f*g; 38656955Sbostic v = u*u; 38756955Sbostic q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); 38835679Sbostic 38956955Sbostic /* case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8, 39056955Sbostic * u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits. 39156955Sbostic * It also adds exactly to |m*log2_hi + log_F_head[j] | < 750 39256955Sbostic */ 39356955Sbostic if (m | j) 39456955Sbostic u1 = u + 513, u1 -= 513; 39524601Szliu 39656955Sbostic /* case 2: |1-x| < 1/256. The m- and j- dependent terms are zero; 39756955Sbostic * u1 = u to 24 bits. 39856955Sbostic */ 39956955Sbostic else 40056955Sbostic u1 = u, TRUNC(u1); 40156955Sbostic u2 = (2.0*(f - F*u1) - u1*f) * g; 40256955Sbostic /* u1 + u2 = 2f/(2F+f) to extra precision. */ 40324601Szliu 40456955Sbostic /* log(x) = log(2^m*F*(1+f/F)) = */ 40556955Sbostic /* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q); */ 40656955Sbostic /* (exact) + (tiny) */ 40724601Szliu 40856955Sbostic u1 += m*logF_head[N] + logF_head[j]; /* exact */ 40956955Sbostic u2 = (u2 + logF_tail[j]) + q; /* tiny */ 41056955Sbostic u2 += logF_tail[N]*m; 41156955Sbostic return (u1 + u2); 41256955Sbostic } 41324601Szliu 414*57442Sbostic /* 415*57442Sbostic * Extra precision variant, returning struct {double a, b;}; 416*57442Sbostic * log(x) = a+b to 63 bits, with a is rounded to 26 bits. 41756955Sbostic */ 41856955Sbostic struct Double 41956955Sbostic #ifdef _ANSI_SOURCE 42056955Sbostic log__D(double x) 42156955Sbostic #else 42256955Sbostic log__D(x) double x; 42356955Sbostic #endif 42456955Sbostic { 42556955Sbostic int m, j; 426*57442Sbostic double F, f, g, q, u, v, u2, one = 1.0; 42756955Sbostic double logb(), ldexp(); 42856955Sbostic volatile double u1; 42956955Sbostic struct Double r; 43024601Szliu 43156955Sbostic /* Argument reduction: 1 <= g < 2; x/2^m = g; */ 43256955Sbostic /* y = F*(1 + f/F) for |f| <= 2^-8 */ 43324601Szliu 43456955Sbostic m = logb(x); 43556955Sbostic g = ldexp(x, -m); 43656955Sbostic if (_IEEE && m == -1022) { 43756955Sbostic j = logb(g), m += j; 43856955Sbostic g = ldexp(g, -j); 43924601Szliu } 44056955Sbostic j = N*(g-1) + .5; 44156955Sbostic F = (1.0/N) * j + 1; 44256955Sbostic f = g - F; 44324601Szliu 44456955Sbostic g = 1/(2*F+f); 44556955Sbostic u = 2*f*g; 44656955Sbostic v = u*u; 44756955Sbostic q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); 44856955Sbostic if (m | j) 44956955Sbostic u1 = u + 513, u1 -= 513; 45056955Sbostic else 45156955Sbostic u1 = u, TRUNC(u1); 45256955Sbostic u2 = (2.0*(f - F*u1) - u1*f) * g; 45324601Szliu 45456955Sbostic u1 += m*logF_head[N] + logF_head[j]; 45524601Szliu 45656955Sbostic u2 += logF_tail[j]; u2 += q; 45756955Sbostic u2 += logF_tail[N]*m; 45856955Sbostic r.a = u1 + u2; /* Only difference is here */ 45956955Sbostic TRUNC(r.a); 46056955Sbostic r.b = (u1 - r.a) + u2; 46156955Sbostic return (r); 46224601Szliu } 463