125c28e83SPiotr Jasiukajtis /* 225c28e83SPiotr Jasiukajtis * CDDL HEADER START 325c28e83SPiotr Jasiukajtis * 425c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the 525c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License"). 625c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License. 725c28e83SPiotr Jasiukajtis * 825c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 925c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing. 1025c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions 1125c28e83SPiotr Jasiukajtis * and limitations under the License. 1225c28e83SPiotr Jasiukajtis * 1325c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each 1425c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1525c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the 1625c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying 1725c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner] 1825c28e83SPiotr Jasiukajtis * 1925c28e83SPiotr Jasiukajtis * CDDL HEADER END 2025c28e83SPiotr Jasiukajtis */ 2125c28e83SPiotr Jasiukajtis 2225c28e83SPiotr Jasiukajtis /* 2325c28e83SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 2425c28e83SPiotr Jasiukajtis */ 2525c28e83SPiotr Jasiukajtis /* 2625c28e83SPiotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 2725c28e83SPiotr Jasiukajtis * Use is subject to license terms. 2825c28e83SPiotr Jasiukajtis */ 2925c28e83SPiotr Jasiukajtis 3025c28e83SPiotr Jasiukajtis /* 3125c28e83SPiotr Jasiukajtis * expl(x) 3225c28e83SPiotr Jasiukajtis * Table driven method 3325c28e83SPiotr Jasiukajtis * Written by K.C. Ng, November 1988. 3425c28e83SPiotr Jasiukajtis * Algorithm : 3525c28e83SPiotr Jasiukajtis * 1. Argument Reduction: given the input x, find r and integer k 3625c28e83SPiotr Jasiukajtis * and j such that 3725c28e83SPiotr Jasiukajtis * x = (32k+j)*ln2 + r, |r| <= (1/64)*ln2 . 3825c28e83SPiotr Jasiukajtis * 3925c28e83SPiotr Jasiukajtis * 2. expl(x) = 2^k * (2^(j/32) + 2^(j/32)*expm1(r)) 4025c28e83SPiotr Jasiukajtis * Note: 4125c28e83SPiotr Jasiukajtis * a. expm1(r) = (2r)/(2-R), R = r - r^2*(t1 + t2*r^2) 4225c28e83SPiotr Jasiukajtis * b. 2^(j/32) is represented as 4325c28e83SPiotr Jasiukajtis * _TBL_expl_hi[j]+_TBL_expl_lo[j] 4425c28e83SPiotr Jasiukajtis * where 4525c28e83SPiotr Jasiukajtis * _TBL_expl_hi[j] = 2^(j/32) rounded 4625c28e83SPiotr Jasiukajtis * _TBL_expl_lo[j] = 2^(j/32) - _TBL_expl_hi[j]. 4725c28e83SPiotr Jasiukajtis * 4825c28e83SPiotr Jasiukajtis * Special cases: 4925c28e83SPiotr Jasiukajtis * expl(INF) is INF, expl(NaN) is NaN; 5025c28e83SPiotr Jasiukajtis * expl(-INF)= 0; 5125c28e83SPiotr Jasiukajtis * for finite argument, only expl(0)=1 is exact. 5225c28e83SPiotr Jasiukajtis * 5325c28e83SPiotr Jasiukajtis * Accuracy: 5425c28e83SPiotr Jasiukajtis * according to an error analysis, the error is always less than 5525c28e83SPiotr Jasiukajtis * an ulp (unit in the last place). 5625c28e83SPiotr Jasiukajtis * 5725c28e83SPiotr Jasiukajtis * Misc. info. 5825c28e83SPiotr Jasiukajtis * For 113 bit long double 5925c28e83SPiotr Jasiukajtis * if x > 1.135652340629414394949193107797076342845e+4 6025c28e83SPiotr Jasiukajtis * then expl(x) overflow; 6125c28e83SPiotr Jasiukajtis * if x < -1.143346274333629787883724384345262150341e+4 6225c28e83SPiotr Jasiukajtis * then expl(x) underflow 6325c28e83SPiotr Jasiukajtis * 6425c28e83SPiotr Jasiukajtis * Constants: 6525c28e83SPiotr Jasiukajtis * Only decimal values are given. We assume that the compiler will convert 6625c28e83SPiotr Jasiukajtis * from decimal to binary accurately enough to produce the correct 6725c28e83SPiotr Jasiukajtis * hexadecimal values. 6825c28e83SPiotr Jasiukajtis */ 6925c28e83SPiotr Jasiukajtis 70*ddc0e0b5SRichard Lowe #pragma weak __expl = expl 7125c28e83SPiotr Jasiukajtis 7225c28e83SPiotr Jasiukajtis #include "libm.h" 7325c28e83SPiotr Jasiukajtis 7425c28e83SPiotr Jasiukajtis extern const long double _TBL_expl_hi[], _TBL_expl_lo[]; 7525c28e83SPiotr Jasiukajtis 7625c28e83SPiotr Jasiukajtis static const long double 7725c28e83SPiotr Jasiukajtis one = 1.0L, 7825c28e83SPiotr Jasiukajtis two = 2.0L, 7925c28e83SPiotr Jasiukajtis ln2_64 = 1.083042469624914545964425189778400898568e-2L, 8025c28e83SPiotr Jasiukajtis ovflthreshold = 1.135652340629414394949193107797076342845e+4L, 8125c28e83SPiotr Jasiukajtis unflthreshold = -1.143346274333629787883724384345262150341e+4L, 8225c28e83SPiotr Jasiukajtis invln2_32 = 4.616624130844682903551758979206054839765e+1L, 8325c28e83SPiotr Jasiukajtis ln2_32hi = 2.166084939249829091928849858592451515688e-2L, 8425c28e83SPiotr Jasiukajtis ln2_32lo = 5.209643502595475652782654157501186731779e-27L; 8525c28e83SPiotr Jasiukajtis 8625c28e83SPiotr Jasiukajtis /* rational approximation coeffs for [-(ln2)/64,(ln2)/64] */ 8725c28e83SPiotr Jasiukajtis static const long double 8825c28e83SPiotr Jasiukajtis t1 = 1.666666666666666666666666666660876387437e-1L, 8925c28e83SPiotr Jasiukajtis t2 = -2.777777777777777777777707812093173478756e-3L, 9025c28e83SPiotr Jasiukajtis t3 = 6.613756613756613482074280932874221202424e-5L, 9125c28e83SPiotr Jasiukajtis t4 = -1.653439153392139954169609822742235851120e-6L, 9225c28e83SPiotr Jasiukajtis t5 = 4.175314851769539751387852116610973796053e-8L; 9325c28e83SPiotr Jasiukajtis 9425c28e83SPiotr Jasiukajtis long double 9525c28e83SPiotr Jasiukajtis expl(long double x) { 9625c28e83SPiotr Jasiukajtis int *px = (int *) &x, ix, j, k, m; 9725c28e83SPiotr Jasiukajtis long double t, r; 9825c28e83SPiotr Jasiukajtis 9925c28e83SPiotr Jasiukajtis ix = px[0]; /* high word of x */ 10025c28e83SPiotr Jasiukajtis if (ix >= 0x7fff0000) 10125c28e83SPiotr Jasiukajtis return (x + x); /* NaN of +inf */ 10225c28e83SPiotr Jasiukajtis if (((unsigned) ix) >= 0xffff0000) 10325c28e83SPiotr Jasiukajtis return (-one / x); /* NaN or -inf */ 10425c28e83SPiotr Jasiukajtis if ((ix & 0x7fffffff) < 0x3fc30000) { 10525c28e83SPiotr Jasiukajtis if ((int) x < 1) 10625c28e83SPiotr Jasiukajtis return (one + x); /* |x|<2^-60 */ 10725c28e83SPiotr Jasiukajtis } 10825c28e83SPiotr Jasiukajtis if (ix > 0) { 10925c28e83SPiotr Jasiukajtis if (x > ovflthreshold) 11025c28e83SPiotr Jasiukajtis return (scalbnl(x, 20000)); 11125c28e83SPiotr Jasiukajtis k = (int) (invln2_32 * (x + ln2_64)); 11225c28e83SPiotr Jasiukajtis } else { 11325c28e83SPiotr Jasiukajtis if (x < unflthreshold) 11425c28e83SPiotr Jasiukajtis return (scalbnl(-x, -40000)); 11525c28e83SPiotr Jasiukajtis k = (int) (invln2_32 * (x - ln2_64)); 11625c28e83SPiotr Jasiukajtis } 11725c28e83SPiotr Jasiukajtis j = k&0x1f; 11825c28e83SPiotr Jasiukajtis m = k>>5; 11925c28e83SPiotr Jasiukajtis t = (long double) k; 12025c28e83SPiotr Jasiukajtis x = (x - t * ln2_32hi) - t * ln2_32lo; 12125c28e83SPiotr Jasiukajtis t = x * x; 12225c28e83SPiotr Jasiukajtis r = (x - t * (t1 + t * (t2 + t * (t3 + t * (t4 + t * t5))))) - two; 12325c28e83SPiotr Jasiukajtis x = _TBL_expl_hi[j] - ((_TBL_expl_hi[j] * (x + x)) / r - 12425c28e83SPiotr Jasiukajtis _TBL_expl_lo[j]); 12525c28e83SPiotr Jasiukajtis return (scalbnl(x, m)); 12625c28e83SPiotr Jasiukajtis } 127