1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma weak __exp = exp 32 33 /* 34 * exp(x) 35 * Hybrid algorithm of Peter Tang's Table driven method (for large 36 * arguments) and an accurate table (for small arguments). 37 * Written by K.C. Ng, November 1988. 38 * Method (large arguments): 39 * 1. Argument Reduction: given the input x, find r and integer k 40 * and j such that 41 * x = (k+j/32)*(ln2) + r, |r| <= (1/64)*ln2 42 * 43 * 2. exp(x) = 2^k * (2^(j/32) + 2^(j/32)*expm1(r)) 44 * a. expm1(r) is approximated by a polynomial: 45 * expm1(r) ~ r + t1*r^2 + t2*r^3 + ... + t5*r^6 46 * Here t1 = 1/2 exactly. 47 * b. 2^(j/32) is represented to twice double precision 48 * as TBL[2j]+TBL[2j+1]. 49 * 50 * Note: If divide were fast enough, we could use another approximation 51 * in 2.a: 52 * expm1(r) ~ (2r)/(2-R), R = r - r^2*(t1 + t2*r^2) 53 * (for the same t1 and t2 as above) 54 * 55 * Special cases: 56 * exp(INF) is INF, exp(NaN) is NaN; 57 * exp(-INF)= 0; 58 * for finite argument, only exp(0)=1 is exact. 59 * 60 * Accuracy: 61 * According to an error analysis, the error is always less than 62 * an ulp (unit in the last place). The largest errors observed 63 * are less than 0.55 ulp for normal results and less than 0.75 ulp 64 * for subnormal results. 65 * 66 * Misc. info. 67 * For IEEE double 68 * if x > 7.09782712893383973096e+02 then exp(x) overflow 69 * if x < -7.45133219101941108420e+02 then exp(x) underflow 70 */ 71 72 #include "libm.h" 73 74 static const double TBL[] = { 75 1.00000000000000000000e+00, 0.00000000000000000000e+00, 76 1.02189714865411662714e+00, 5.10922502897344389359e-17, 77 1.04427378242741375480e+00, 8.55188970553796365958e-17, 78 1.06714040067682369717e+00, -7.89985396684158212226e-17, 79 1.09050773266525768967e+00, -3.04678207981247114697e-17, 80 1.11438674259589243221e+00, 1.04102784568455709549e-16, 81 1.13878863475669156458e+00, 8.91281267602540777782e-17, 82 1.16372485877757747552e+00, 3.82920483692409349872e-17, 83 1.18920711500272102690e+00, 3.98201523146564611098e-17, 84 1.21524735998046895524e+00, -7.71263069268148813091e-17, 85 1.24185781207348400201e+00, 4.65802759183693679123e-17, 86 1.26905095719173321989e+00, 2.66793213134218609523e-18, 87 1.29683955465100964055e+00, 2.53825027948883149593e-17, 88 1.32523664315974132322e+00, -2.85873121003886075697e-17, 89 1.35425554693689265129e+00, 7.70094837980298946162e-17, 90 1.38390988196383202258e+00, -6.77051165879478628716e-17, 91 1.41421356237309514547e+00, -9.66729331345291345105e-17, 92 1.44518080697704665027e+00, -3.02375813499398731940e-17, 93 1.47682614593949934623e+00, -3.48399455689279579579e-17, 94 1.50916442759342284141e+00, -1.01645532775429503911e-16, 95 1.54221082540794074411e+00, 7.94983480969762085616e-17, 96 1.57598084510788649659e+00, -1.01369164712783039808e-17, 97 1.61049033194925428347e+00, 2.47071925697978878522e-17, 98 1.64575547815396494578e+00, -1.01256799136747726038e-16, 99 1.68179283050742900407e+00, 8.19901002058149652013e-17, 100 1.71861929812247793414e+00, -1.85138041826311098821e-17, 101 1.75625216037329945351e+00, 2.96014069544887330703e-17, 102 1.79470907500310716820e+00, 1.82274584279120867698e-17, 103 1.83400808640934243066e+00, 3.28310722424562658722e-17, 104 1.87416763411029996256e+00, -6.12276341300414256164e-17, 105 1.91520656139714740007e+00, -1.06199460561959626376e-16, 106 1.95714412417540017941e+00, 8.96076779103666776760e-17, 107 }; 108 109 /* 110 * For i = 0, ..., 66, 111 * TBL2[2*i] is a double precision number near (i+1)*2^-6, and 112 * TBL2[2*i+1] = exp(TBL2[2*i]) to within a relative error less 113 * than 2^-60. 114 * 115 * For i = 67, ..., 133, 116 * TBL2[2*i] is a double precision number near -(i+1)*2^-6, and 117 * TBL2[2*i+1] = exp(TBL2[2*i]) to within a relative error less 118 * than 2^-60. 119 */ 120 static const double TBL2[] = { 121 1.56249999999984491572e-02, 1.01574770858668417262e+00, 122 3.12499999999998716305e-02, 1.03174340749910253834e+00, 123 4.68750000000011102230e-02, 1.04799100201663386578e+00, 124 6.24999999999990632493e-02, 1.06449445891785843266e+00, 125 7.81249999999999444888e-02, 1.08125780744903954300e+00, 126 9.37500000000013322676e-02, 1.09828514030782731226e+00, 127 1.09375000000001346145e-01, 1.11558061464248226002e+00, 128 1.24999999999999417133e-01, 1.13314845306682565607e+00, 129 1.40624999999995337063e-01, 1.15099294469117108264e+00, 130 1.56249999999996141975e-01, 1.16911844616949989195e+00, 131 1.71874999999992894573e-01, 1.18752938276309216725e+00, 132 1.87500000000000888178e-01, 1.20623024942098178158e+00, 133 2.03124999999361649516e-01, 1.22522561187652545556e+00, 134 2.18750000000000416334e-01, 1.24452010776609567344e+00, 135 2.34375000000003524958e-01, 1.26411844775347081971e+00, 136 2.50000000000006328271e-01, 1.28402541668774961003e+00, 137 2.65624999999982791543e-01, 1.30424587476761533189e+00, 138 2.81249999999993727240e-01, 1.32478475872885725906e+00, 139 2.96875000000003275158e-01, 1.34564708304941493822e+00, 140 3.12500000000002886580e-01, 1.36683794117380030819e+00, 141 3.28124999999993394173e-01, 1.38836250675661765364e+00, 142 3.43749999999998612221e-01, 1.41022603492570874906e+00, 143 3.59374999999992450483e-01, 1.43243386356506730017e+00, 144 3.74999999999991395772e-01, 1.45499141461818881638e+00, 145 3.90624999999997613020e-01, 1.47790419541173490003e+00, 146 4.06249999999991895372e-01, 1.50117780000011058483e+00, 147 4.21874999999996613820e-01, 1.52481791053132154090e+00, 148 4.37500000000004607426e-01, 1.54883029863414023453e+00, 149 4.53125000000004274359e-01, 1.57322082682725961078e+00, 150 4.68750000000008326673e-01, 1.59799544995064657371e+00, 151 4.84374999999985456078e-01, 1.62316021661928200359e+00, 152 4.99999999999997335465e-01, 1.64872127070012375327e+00, 153 5.15625000000000222045e-01, 1.67468485281178436352e+00, 154 5.31250000000003441691e-01, 1.70105730184840653330e+00, 155 5.46874999999999111822e-01, 1.72784505652716169344e+00, 156 5.62499999999999333866e-01, 1.75505465696029738787e+00, 157 5.78124999999993338662e-01, 1.78269274625180318417e+00, 158 5.93749999999999666933e-01, 1.81076607211938656050e+00, 159 6.09375000000003441691e-01, 1.83928148854178719063e+00, 160 6.24999999999995559108e-01, 1.86824595743221411048e+00, 161 6.40625000000009103829e-01, 1.89766655033813602671e+00, 162 6.56249999999993782751e-01, 1.92755045016753268072e+00, 163 6.71875000000002109424e-01, 1.95790495294292221651e+00, 164 6.87499999999992450483e-01, 1.98873746958227681780e+00, 165 7.03125000000004996004e-01, 2.02005552770870666635e+00, 166 7.18750000000007105427e-01, 2.05186677348799140219e+00, 167 7.34375000000008770762e-01, 2.08417897349558689513e+00, 168 7.49999999999983901766e-01, 2.11700001661264058939e+00, 169 7.65624999999997002398e-01, 2.15033791595229351046e+00, 170 7.81250000000005884182e-01, 2.18420081081563077774e+00, 171 7.96874999999991451283e-01, 2.21859696867912603579e+00, 172 8.12500000000000000000e-01, 2.25353478721320854561e+00, 173 8.28125000000008215650e-01, 2.28902279633221983346e+00, 174 8.43749999999997890576e-01, 2.32506966027711614586e+00, 175 8.59374999999999444888e-01, 2.36168417973090827289e+00, 176 8.75000000000003219647e-01, 2.39887529396710563745e+00, 177 8.90625000000013433699e-01, 2.43665208303232461162e+00, 178 9.06249999999980571097e-01, 2.47502376996297712708e+00, 179 9.21874999999984456878e-01, 2.51399972303748420188e+00, 180 9.37500000000001887379e-01, 2.55358945806293169412e+00, 181 9.53125000000003330669e-01, 2.59380264069854327147e+00, 182 9.68749999999989119814e-01, 2.63464908881560244680e+00, 183 9.84374999999997890576e-01, 2.67613877489447116176e+00, 184 1.00000000000001154632e+00, 2.71828182845907662113e+00, 185 1.01562499999999333866e+00, 2.76108853855008318234e+00, 186 1.03124999999995980993e+00, 2.80456935623711389738e+00, 187 1.04687499999999933387e+00, 2.84873489717039740654e+00, 188 -1.56249999999999514277e-02, 9.84496437005408453480e-01, 189 -3.12499999999955972718e-02, 9.69233234476348348707e-01, 190 -4.68749999999993824384e-02, 9.54206665969188905230e-01, 191 -6.24999999999976130205e-02, 9.39413062813478028090e-01, 192 -7.81249999999989314103e-02, 9.24848813216205822840e-01, 193 -9.37499999999995975442e-02, 9.10510361380034494161e-01, 194 -1.09374999999998584466e-01, 8.96394206635151680196e-01, 195 -1.24999999999998556710e-01, 8.82496902584596676355e-01, 196 -1.40624999999999361622e-01, 8.68815056262843721235e-01, 197 -1.56249999999999111822e-01, 8.55345327307423297647e-01, 198 -1.71874999999924144012e-01, 8.42084427143446223596e-01, 199 -1.87499999999996752598e-01, 8.29029118180403035154e-01, 200 -2.03124999999988037347e-01, 8.16176213022349550386e-01, 201 -2.18749999999995947686e-01, 8.03522573689063990265e-01, 202 -2.34374999999996419531e-01, 7.91065110850298847112e-01, 203 -2.49999999999996280753e-01, 7.78800783071407765057e-01, 204 -2.65624999999999888978e-01, 7.66726596070820165529e-01, 205 -2.81249999999989397370e-01, 7.54839601989015340777e-01, 206 -2.96874999999996114219e-01, 7.43136898668761203268e-01, 207 -3.12499999999999555911e-01, 7.31615628946642115871e-01, 208 -3.28124999999993782751e-01, 7.20272979955444259126e-01, 209 -3.43749999999997946087e-01, 7.09106182437399867879e-01, 210 -3.59374999999994337863e-01, 6.98112510068129799023e-01, 211 -3.74999999999994615418e-01, 6.87289278790975899369e-01, 212 -3.90624999999999000799e-01, 6.76633846161729612945e-01, 213 -4.06249999999947264406e-01, 6.66143610703522903727e-01, 214 -4.21874999999988453681e-01, 6.55816011271509125002e-01, 215 -4.37499999999999111822e-01, 6.45648526427892610613e-01, 216 -4.53124999999999278355e-01, 6.35638673826052436056e-01, 217 -4.68749999999999278355e-01, 6.25784009604591573428e-01, 218 -4.84374999999992894573e-01, 6.16082127790682609891e-01, 219 -4.99999999999998168132e-01, 6.06530659712634534486e-01, 220 -5.15625000000000000000e-01, 5.97127273421627413619e-01, 221 -5.31249999999989785948e-01, 5.87869673122352498496e-01, 222 -5.46874999999972688514e-01, 5.78755598612500032907e-01, 223 -5.62500000000000000000e-01, 5.69782824730923009859e-01, 224 -5.78124999999992339461e-01, 5.60949160814475100700e-01, 225 -5.93749999999948707696e-01, 5.52252450163048691500e-01, 226 -6.09374999999552580121e-01, 5.43690569513243682209e-01, 227 -6.24999999999984789945e-01, 5.35261428518998383375e-01, 228 -6.40624999999983457677e-01, 5.26962969243379708573e-01, 229 -6.56249999999998334665e-01, 5.18793165653890220312e-01, 230 -6.71874999999943378626e-01, 5.10750023129039609771e-01, 231 -6.87499999999997002398e-01, 5.02831577970942467104e-01, 232 -7.03124999999991118216e-01, 4.95035896926202978463e-01, 233 -7.18749999999991340260e-01, 4.87361076713623331269e-01, 234 -7.34374999999985678123e-01, 4.79805243559684402310e-01, 235 -7.49999999999997335465e-01, 4.72366552741015965911e-01, 236 -7.65624999999993782751e-01, 4.65043188134059204408e-01, 237 -7.81249999999863220523e-01, 4.57833361771676883301e-01, 238 -7.96874999999998112621e-01, 4.50735313406363247157e-01, 239 -8.12499999999990119015e-01, 4.43747310081084256339e-01, 240 -8.28124999999996003197e-01, 4.36867645705559026759e-01, 241 -8.43749999999988120614e-01, 4.30094640640067360504e-01, 242 -8.59374999999994115818e-01, 4.23426641285265303871e-01, 243 -8.74999999999977129406e-01, 4.16862019678517936594e-01, 244 -8.90624999999983346655e-01, 4.10399173096376801428e-01, 245 -9.06249999999991784350e-01, 4.04036523663345414903e-01, 246 -9.21874999999994004796e-01, 3.97772517966614058693e-01, 247 -9.37499999999994337863e-01, 3.91605626676801210628e-01, 248 -9.53124999999999444888e-01, 3.85534344174578935682e-01, 249 -9.68749999999986677324e-01, 3.79557188183094640355e-01, 250 -9.84374999999992339461e-01, 3.73672699406045860648e-01, 251 -9.99999999999995892175e-01, 3.67879441171443832825e-01, 252 -1.01562499999994315658e+00, 3.62175999080846300338e-01, 253 -1.03124999999991096011e+00, 3.56560980663978732697e-01, 254 -1.04687499999999067413e+00, 3.51033015038813400732e-01, 255 }; 256 257 static const double C[] = { 258 0.5, 259 4.61662413084468283841e+01, /* 0x40471547, 0x652b82fe */ 260 2.16608493865351192653e-02, /* 0x3f962e42, 0xfee00000 */ 261 5.96317165397058656257e-12, /* 0x3d9a39ef, 0x35793c76 */ 262 1.6666666666526086527e-1, /* 3fc5555555548f7c */ 263 4.1666666666226079285e-2, /* 3fa5555555545d4e */ 264 8.3333679843421958056e-3, /* 3f811115b7aa905e */ 265 1.3888949086377719040e-3, /* 3f56c1728d739765 */ 266 1.0, 267 0.0, 268 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ 269 7.45133219101941108420e+02, /* 0x40874910, 0xD52D3051 */ 270 5.55111512312578270212e-17, /* 0x3c900000, 0x00000000 */ 271 }; 272 273 #define half C[0] 274 #define invln2_32 C[1] 275 #define ln2_32hi C[2] 276 #define ln2_32lo C[3] 277 #define t2 C[4] 278 #define t3 C[5] 279 #define t4 C[6] 280 #define t5 C[7] 281 #define one C[8] 282 #define zero C[9] 283 #define threshold1 C[10] 284 #define threshold2 C[11] 285 #define twom54 C[12] 286 287 double 288 exp(double x) 289 { 290 double y, z, t; 291 int hx, ix, k, j, m; 292 293 ix = ((int *)&x)[HIWORD]; 294 hx = ix & ~0x80000000; 295 296 if (hx < 0x3ff0a2b2) { /* |x| < 3/2 ln 2 */ 297 if (hx < 0x3f862e42) { /* |x| < 1/64 ln 2 */ 298 if (hx < 0x3ed00000) { /* |x| < 2^-18 */ 299 volatile int dummy __unused; 300 301 dummy = (int)x; /* raise inexact if x != 0 */ 302 #ifdef lint 303 dummy = dummy; 304 #endif 305 306 if (hx < 0x3e300000) 307 return (one + x); 308 309 return (one + x * (one + half * x)); 310 } 311 312 t = x * x; 313 y = x + (t * (half + x * t2) + (t * t) * (t3 + x * t4 + 314 t * t5)); 315 return (one + y); 316 } 317 318 /* find the multiple of 2^-6 nearest x */ 319 k = hx >> 20; 320 j = (0x00100000 | (hx & 0x000fffff)) >> (0x40c - k); 321 j = (j - 1) & ~1; 322 323 if (ix < 0) 324 j += 134; 325 326 z = x - TBL2[j]; 327 t = z * z; 328 y = z + (t * (half + z * t2) + (t * t) * (t3 + z * t4 + t * 329 t5)); 330 return (TBL2[j + 1] + TBL2[j + 1] * y); 331 } 332 333 if (hx >= 0x40862e42) { /* x is large, infinite, or nan */ 334 if (hx >= 0x7ff00000) { 335 if (ix == 0xfff00000 && ((int *)&x)[LOWORD] == 0) 336 return (zero); 337 338 return (x * x); 339 } 340 341 if (x > threshold1) 342 return (_SVID_libm_err(x, x, 6)); 343 344 if (-x > threshold2) 345 return (_SVID_libm_err(x, x, 7)); 346 } 347 348 t = invln2_32 * x; 349 350 if (ix < 0) 351 t -= half; 352 else 353 t += half; 354 355 k = (int)t; 356 j = (k & 0x1f) << 1; 357 m = k >> 5; 358 z = (x - k * ln2_32hi) - k * ln2_32lo; 359 360 /* z is now in primary range */ 361 t = z * z; 362 y = z + (t * (half + z * t2) + (t * t) * (t3 + z * t4 + t * t5)); 363 y = TBL[j] + (TBL[j + 1] + TBL[j] * y); 364 365 if (m < -1021) { 366 ((int *)&y)[HIWORD] += (m + 54) << 20; 367 return (twom54 * y); 368 } 369 370 ((int *)&y)[HIWORD] += m << 20; 371 return (y); 372 }