1238722Skargl/*- 2251315Skargl * Copyright (c) 2009-2013 Steven G. Kargl 3238722Skargl * All rights reserved. 4238722Skargl * 5238722Skargl * Redistribution and use in source and binary forms, with or without 6238722Skargl * modification, are permitted provided that the following conditions 7238722Skargl * are met: 8238722Skargl * 1. Redistributions of source code must retain the above copyright 9238722Skargl * notice unmodified, this list of conditions, and the following 10238722Skargl * disclaimer. 11238722Skargl * 2. Redistributions in binary form must reproduce the above copyright 12238722Skargl * notice, this list of conditions and the following disclaimer in the 13238722Skargl * documentation and/or other materials provided with the distribution. 14238722Skargl * 15238722Skargl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16238722Skargl * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17238722Skargl * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18238722Skargl * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19238722Skargl * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20238722Skargl * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21238722Skargl * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22238722Skargl * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23238722Skargl * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24238722Skargl * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25251337Skargl * 26251337Skargl * Optimized by Bruce D. Evans. 27238722Skargl */ 28238722Skargl 29238722Skargl#include <sys/cdefs.h> 30238722Skargl__FBSDID("$FreeBSD$"); 31238722Skargl 32240864Skargl/* 33240864Skargl * ld128 version of s_expl.c. See ../ld80/s_expl.c for most comments. 34240864Skargl */ 35240864Skargl 36238722Skargl#include <float.h> 37238722Skargl 38238783Skargl#include "fpmath.h" 39238722Skargl#include "math.h" 40238722Skargl#include "math_private.h" 41260066Skargl#include "k_expl.h" 42238722Skargl 43260066Skargl/* XXX Prevent compilers from erroneously constant folding these: */ 44260066Skarglstatic const volatile long double 45260066Skarglhuge = 0x1p10000L, 46260066Skargltiny = 0x1p-10000L; 47238722Skargl 48251334Skarglstatic const long double 49251345Skargltwom10000 = 0x1p-10000L; 50238722Skargl 51238722Skarglstatic const long double 52251334Skargl/* log(2**16384 - 0.5) rounded towards zero: */ 53251334Skargl/* log(2**16384 - 0.5 + 1) rounded towards zero for expm1l() is the same: */ 54238722Skarglo_threshold = 11356.523406294143949491931077970763428L, 55251334Skargl/* log(2**(-16381-64-1)) rounded towards zero: */ 56240864Skarglu_threshold = -11433.462743336297878837243843452621503L; 57238722Skargl 58238722Skargllong double 59238722Skarglexpl(long double x) 60238722Skargl{ 61260066Skargl union IEEEl2bits u; 62260066Skargl long double hi, lo, t, twopk; 63260066Skargl int k; 64251339Skargl uint16_t hx, ix; 65238722Skargl 66260066Skargl DOPRINT_START(&x); 67260066Skargl 68238722Skargl /* Filter out exceptional cases. */ 69238722Skargl u.e = x; 70238722Skargl hx = u.xbits.expsign; 71238923Skargl ix = hx & 0x7fff; 72238722Skargl if (ix >= BIAS + 13) { /* |x| >= 8192 or x is NaN */ 73238722Skargl if (ix == BIAS + LDBL_MAX_EXP) { 74251335Skargl if (hx & 0x8000) /* x is -Inf or -NaN */ 75260066Skargl RETURNP(-1 / x); 76260066Skargl RETURNP(x + x); /* x is +Inf or +NaN */ 77238722Skargl } 78238722Skargl if (x > o_threshold) 79260066Skargl RETURNP(huge * huge); 80238722Skargl if (x < u_threshold) 81260066Skargl RETURNP(tiny * tiny); 82251335Skargl } else if (ix < BIAS - 114) { /* |x| < 0x1p-114 */ 83260066Skargl RETURN2P(1, x); /* 1 with inexact iff x != 0 */ 84238722Skargl } 85238722Skargl 86251339Skargl ENTERI(); 87251339Skargl 88260066Skargl twopk = 1; 89260066Skargl __k_expl(x, &hi, &lo, &k); 90260066Skargl t = SUM2P(hi, lo); 91238722Skargl 92260066Skargl /* Scale by 2**k. */ 93251339Skargl /* XXX sparc64 multiplication is so slow that scalbnl() is faster. */ 94238722Skargl if (k >= LDBL_MIN_EXP) { 95238722Skargl if (k == LDBL_MAX_EXP) 96251339Skargl RETURNI(t * 2 * 0x1p16383L); 97260066Skargl SET_LDBL_EXPSIGN(twopk, BIAS + k); 98251339Skargl RETURNI(t * twopk); 99238722Skargl } else { 100260066Skargl SET_LDBL_EXPSIGN(twopk, BIAS + k + 10000); 101260066Skargl RETURNI(t * twopk * twom10000); 102238722Skargl } 103238722Skargl} 104251343Skargl 105251343Skargl/* 106251343Skargl * Our T1 and T2 are chosen to be approximately the points where method 107251343Skargl * A and method B have the same accuracy. Tang's T1 and T2 are the 108251343Skargl * points where method A's accuracy changes by a full bit. For Tang, 109251343Skargl * this drop in accuracy makes method A immediately less accurate than 110251343Skargl * method B, but our larger INTERVALS makes method A 2 bits more 111251343Skargl * accurate so it remains the most accurate method significantly 112251343Skargl * closer to the origin despite losing the full bit in our extended 113251343Skargl * range for it. 114251343Skargl * 115251343Skargl * Split the interval [T1, T2] into two intervals [T1, T3] and [T3, T2]. 116251343Skargl * Setting T3 to 0 would require the |x| < 0x1p-113 condition to appear 117251343Skargl * in both subintervals, so set T3 = 2**-5, which places the condition 118251343Skargl * into the [T1, T3] interval. 119260066Skargl * 120260066Skargl * XXX we now do this more to (partially) balance the number of terms 121260066Skargl * in the C and D polys than to avoid checking the condition in both 122260066Skargl * intervals. 123260066Skargl * 124260066Skargl * XXX these micro-optimizations are excessive. 125251343Skargl */ 126251343Skarglstatic const double 127251343SkarglT1 = -0.1659, /* ~-30.625/128 * log(2) */ 128251343SkarglT2 = 0.1659, /* ~30.625/128 * log(2) */ 129251343SkarglT3 = 0.03125; 130251343Skargl 131251343Skargl/* 132251343Skargl * Domain [-0.1659, 0.03125], range ~[2.9134e-44, 1.8404e-37]: 133251343Skargl * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-122.03 134262613Sdim * 135260066Skargl * XXX none of the long double C or D coeffs except C10 is correctly printed. 136260066Skargl * If you re-print their values in %.35Le format, the result is always 137260066Skargl * different. For example, the last 2 digits in C3 should be 59, not 67. 138260066Skargl * 67 is apparently from rounding an extra-precision value to 36 decimal 139260066Skargl * places. 140251343Skargl */ 141251343Skarglstatic const long double 142251343SkarglC3 = 1.66666666666666666666666666666666667e-1L, 143251343SkarglC4 = 4.16666666666666666666666666666666645e-2L, 144251343SkarglC5 = 8.33333333333333333333333333333371638e-3L, 145251343SkarglC6 = 1.38888888888888888888888888891188658e-3L, 146251343SkarglC7 = 1.98412698412698412698412697235950394e-4L, 147251343SkarglC8 = 2.48015873015873015873015112487849040e-5L, 148251343SkarglC9 = 2.75573192239858906525606685484412005e-6L, 149251343SkarglC10 = 2.75573192239858906612966093057020362e-7L, 150251343SkarglC11 = 2.50521083854417203619031960151253944e-8L, 151251343SkarglC12 = 2.08767569878679576457272282566520649e-9L, 152251343SkarglC13 = 1.60590438367252471783548748824255707e-10L; 153251343Skargl 154260066Skargl/* 155260066Skargl * XXX this has 1 more coeff than needed. 156260066Skargl * XXX can start the double coeffs but not the double mults at C10. 157260066Skargl * With my coeffs (C10-C17 double; s = best_s): 158260066Skargl * Domain [-0.1659, 0.03125], range ~[-1.1976e-37, 1.1976e-37]: 159260066Skargl * |(exp(x)-1-x-x**2/2)/x - p(x)| ~< 2**-122.65 160260066Skargl */ 161251343Skarglstatic const double 162251343SkarglC14 = 1.1470745580491932e-11, /* 0x1.93974a81dae30p-37 */ 163251343SkarglC15 = 7.6471620181090468e-13, /* 0x1.ae7f3820adab1p-41 */ 164251343SkarglC16 = 4.7793721460260450e-14, /* 0x1.ae7cd18a18eacp-45 */ 165251343SkarglC17 = 2.8074757356658877e-15, /* 0x1.949992a1937d9p-49 */ 166251343SkarglC18 = 1.4760610323699476e-16; /* 0x1.545b43aabfbcdp-53 */ 167251343Skargl 168251343Skargl/* 169251343Skargl * Domain [0.03125, 0.1659], range ~[-2.7676e-37, -1.0367e-38]: 170251343Skargl * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-121.44 171251343Skargl */ 172251343Skarglstatic const long double 173251343SkarglD3 = 1.66666666666666666666666666666682245e-1L, 174251343SkarglD4 = 4.16666666666666666666666666634228324e-2L, 175251343SkarglD5 = 8.33333333333333333333333364022244481e-3L, 176251343SkarglD6 = 1.38888888888888888888887138722762072e-3L, 177251343SkarglD7 = 1.98412698412698412699085805424661471e-4L, 178251343SkarglD8 = 2.48015873015873015687993712101479612e-5L, 179251343SkarglD9 = 2.75573192239858944101036288338208042e-6L, 180251343SkarglD10 = 2.75573192239853161148064676533754048e-7L, 181251343SkarglD11 = 2.50521083855084570046480450935267433e-8L, 182251343SkarglD12 = 2.08767569819738524488686318024854942e-9L, 183251343SkarglD13 = 1.60590442297008495301927448122499313e-10L; 184251343Skargl 185260066Skargl/* 186260066Skargl * XXX this has 1 more coeff than needed. 187260066Skargl * XXX can start the double coeffs but not the double mults at D11. 188260066Skargl * With my coeffs (D11-D16 double): 189260066Skargl * Domain [0.03125, 0.1659], range ~[-1.1980e-37, 1.1980e-37]: 190260066Skargl * |(exp(x)-1-x-x**2/2)/x - p(x)| ~< 2**-122.65 191260066Skargl */ 192251343Skarglstatic const double 193251343SkarglD14 = 1.1470726176204336e-11, /* 0x1.93971dc395d9ep-37 */ 194251343SkarglD15 = 7.6478532249581686e-13, /* 0x1.ae892e3D16fcep-41 */ 195251343SkarglD16 = 4.7628892832607741e-14, /* 0x1.ad00Dfe41feccp-45 */ 196251343SkarglD17 = 3.0524857220358650e-15; /* 0x1.D7e8d886Df921p-49 */ 197251343Skargl 198251343Skargllong double 199251343Skarglexpm1l(long double x) 200251343Skargl{ 201251343Skargl union IEEEl2bits u, v; 202251343Skargl long double hx2_hi, hx2_lo, q, r, r1, t, twomk, twopk, x_hi; 203251343Skargl long double x_lo, x2; 204251343Skargl double dr, dx, fn, r2; 205251343Skargl int k, n, n2; 206251343Skargl uint16_t hx, ix; 207251343Skargl 208260066Skargl DOPRINT_START(&x); 209260066Skargl 210251343Skargl /* Filter out exceptional cases. */ 211251343Skargl u.e = x; 212251343Skargl hx = u.xbits.expsign; 213251343Skargl ix = hx & 0x7fff; 214251343Skargl if (ix >= BIAS + 7) { /* |x| >= 128 or x is NaN */ 215251343Skargl if (ix == BIAS + LDBL_MAX_EXP) { 216251343Skargl if (hx & 0x8000) /* x is -Inf or -NaN */ 217260066Skargl RETURNP(-1 / x - 1); 218260066Skargl RETURNP(x + x); /* x is +Inf or +NaN */ 219251343Skargl } 220251343Skargl if (x > o_threshold) 221260066Skargl RETURNP(huge * huge); 222251343Skargl /* 223251343Skargl * expm1l() never underflows, but it must avoid 224251343Skargl * unrepresentable large negative exponents. We used a 225251343Skargl * much smaller threshold for large |x| above than in 226251343Skargl * expl() so as to handle not so large negative exponents 227251343Skargl * in the same way as large ones here. 228251343Skargl */ 229251343Skargl if (hx & 0x8000) /* x <= -128 */ 230260066Skargl RETURN2P(tiny, -1); /* good for x < -114ln2 - eps */ 231251343Skargl } 232251343Skargl 233251343Skargl ENTERI(); 234251343Skargl 235251343Skargl if (T1 < x && x < T2) { 236251343Skargl x2 = x * x; 237251343Skargl dx = x; 238251343Skargl 239251343Skargl if (x < T3) { 240251343Skargl if (ix < BIAS - 113) { /* |x| < 0x1p-113 */ 241251343Skargl /* x (rounded) with inexact if x != 0: */ 242260066Skargl RETURNPI(x == 0 ? x : 243251343Skargl (0x1p200 * x + fabsl(x)) * 0x1p-200); 244251343Skargl } 245251343Skargl q = x * x2 * C3 + x2 * x2 * (C4 + x * (C5 + x * (C6 + 246251343Skargl x * (C7 + x * (C8 + x * (C9 + x * (C10 + 247251343Skargl x * (C11 + x * (C12 + x * (C13 + 248251343Skargl dx * (C14 + dx * (C15 + dx * (C16 + 249251343Skargl dx * (C17 + dx * C18)))))))))))))); 250251343Skargl } else { 251251343Skargl q = x * x2 * D3 + x2 * x2 * (D4 + x * (D5 + x * (D6 + 252251343Skargl x * (D7 + x * (D8 + x * (D9 + x * (D10 + 253251343Skargl x * (D11 + x * (D12 + x * (D13 + 254251343Skargl dx * (D14 + dx * (D15 + dx * (D16 + 255251343Skargl dx * D17))))))))))))); 256251343Skargl } 257251343Skargl 258251343Skargl x_hi = (float)x; 259251343Skargl x_lo = x - x_hi; 260251343Skargl hx2_hi = x_hi * x_hi / 2; 261251343Skargl hx2_lo = x_lo * (x + x_hi) / 2; 262251343Skargl if (ix >= BIAS - 7) 263260066Skargl RETURN2PI(hx2_hi + x_hi, hx2_lo + x_lo + q); 264251343Skargl else 265260066Skargl RETURN2PI(x, hx2_lo + q + hx2_hi); 266251343Skargl } 267251343Skargl 268251343Skargl /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ 269251343Skargl /* Use a specialized rint() to get fn. Assume round-to-nearest. */ 270251343Skargl fn = (double)x * INV_L + 0x1.8p52 - 0x1.8p52; 271251343Skargl#if defined(HAVE_EFFICIENT_IRINT) 272251343Skargl n = irint(fn); 273251343Skargl#else 274251343Skargl n = (int)fn; 275251343Skargl#endif 276251343Skargl n2 = (unsigned)n % INTERVALS; 277251343Skargl k = n >> LOG2_INTERVALS; 278251343Skargl r1 = x - fn * L1; 279251343Skargl r2 = fn * -L2; 280251343Skargl r = r1 + r2; 281251343Skargl 282251343Skargl /* Prepare scale factor. */ 283251343Skargl v.e = 1; 284251343Skargl v.xbits.expsign = BIAS + k; 285251343Skargl twopk = v.e; 286251343Skargl 287251343Skargl /* 288251343Skargl * Evaluate lower terms of 289251343Skargl * expl(endpoint[n2] + r1 + r2) = tbl[n2] * expl(r1 + r2). 290251343Skargl */ 291251343Skargl dr = r; 292251343Skargl q = r2 + r * r * (A2 + r * (A3 + r * (A4 + r * (A5 + r * (A6 + 293251343Skargl dr * (A7 + dr * (A8 + dr * (A9 + dr * A10)))))))); 294251343Skargl 295251343Skargl t = tbl[n2].lo + tbl[n2].hi; 296251343Skargl 297251343Skargl if (k == 0) { 298260066Skargl t = SUM2P(tbl[n2].hi - 1, tbl[n2].lo * (r1 + 1) + t * q + 299260066Skargl tbl[n2].hi * r1); 300251343Skargl RETURNI(t); 301251343Skargl } 302251343Skargl if (k == -1) { 303260066Skargl t = SUM2P(tbl[n2].hi - 2, tbl[n2].lo * (r1 + 1) + t * q + 304260066Skargl tbl[n2].hi * r1); 305251343Skargl RETURNI(t / 2); 306251343Skargl } 307251343Skargl if (k < -7) { 308260066Skargl t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); 309251343Skargl RETURNI(t * twopk - 1); 310251343Skargl } 311251343Skargl if (k > 2 * LDBL_MANT_DIG - 1) { 312260066Skargl t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); 313251343Skargl if (k == LDBL_MAX_EXP) 314251343Skargl RETURNI(t * 2 * 0x1p16383L - 1); 315251343Skargl RETURNI(t * twopk - 1); 316251343Skargl } 317251343Skargl 318251343Skargl v.xbits.expsign = BIAS - k; 319251343Skargl twomk = v.e; 320251343Skargl 321251343Skargl if (k > LDBL_MANT_DIG - 1) 322260066Skargl t = SUM2P(tbl[n2].hi, tbl[n2].lo - twomk + t * (q + r1)); 323251343Skargl else 324260066Skargl t = SUM2P(tbl[n2].hi - twomk, tbl[n2].lo + t * (q + r1)); 325251343Skargl RETURNI(t * twopk); 326251343Skargl} 327