[Midnightbsd-cvs] src [10596] trunk/lib/msun/ld80: sync ld80
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Jun 9 11:11:52 EDT 2018
Revision: 10596
http://svnweb.midnightbsd.org/src/?rev=10596
Author: laffer1
Date: 2018-06-09 11:11:51 -0400 (Sat, 09 Jun 2018)
Log Message:
-----------
sync ld80
Modified Paths:
--------------
trunk/lib/msun/ld80/e_rem_pio2l.h
trunk/lib/msun/ld80/invtrig.c
trunk/lib/msun/ld80/invtrig.h
trunk/lib/msun/ld80/k_cosl.c
trunk/lib/msun/ld80/k_sinl.c
trunk/lib/msun/ld80/k_tanl.c
trunk/lib/msun/ld80/s_exp2l.c
trunk/lib/msun/ld80/s_nanl.c
Added Paths:
-----------
trunk/lib/msun/ld80/e_lgammal_r.c
trunk/lib/msun/ld80/k_expl.h
trunk/lib/msun/ld80/s_erfl.c
trunk/lib/msun/ld80/s_expl.c
trunk/lib/msun/ld80/s_logl.c
Added: trunk/lib/msun/ld80/e_lgammal_r.c
===================================================================
--- trunk/lib/msun/ld80/e_lgammal_r.c (rev 0)
+++ trunk/lib/msun/ld80/e_lgammal_r.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,359 @@
+/* $MidnightBSD$ */
+/* @(#)e_lgamma_r.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/e_lgammal_r.c 284810 2015-06-25 13:01:10Z tijl $");
+
+/*
+ * See e_lgamma_r.c for complete comments.
+ *
+ * Converted to long double by Steven G. Kargl.
+ */
+
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
+#include "math.h"
+#include "math_private.h"
+
+static const volatile double vzero = 0;
+
+static const double
+zero= 0,
+half= 0.5,
+one = 1;
+
+static const union IEEEl2bits
+piu = LD80C(0xc90fdaa22168c235, 1, 3.14159265358979323851e+00L);
+#define pi (piu.e)
+/*
+ * Domain y in [0x1p-70, 0.27], range ~[-4.5264e-22, 4.5264e-22]:
+ * |(lgamma(2 - y) + y / 2) / y - a(y)| < 2**-70.9
+ */
+static const union IEEEl2bits
+a0u = LD80C(0x9e233f1bed863d26, -4, 7.72156649015328606028e-02L),
+a1u = LD80C(0xa51a6625307d3249, -2, 3.22467033424113218889e-01L),
+a2u = LD80C(0x89f000d2abafda8c, -4, 6.73523010531979398946e-02L),
+a3u = LD80C(0xa8991563eca75f26, -6, 2.05808084277991211934e-02L),
+a4u = LD80C(0xf2027e10634ce6b6, -8, 7.38555102796070454026e-03L),
+a5u = LD80C(0xbd6eb76dd22187f4, -9, 2.89051035162703932972e-03L),
+a6u = LD80C(0x9c562ab05e0458ed, -10, 1.19275351624639999297e-03L),
+a7u = LD80C(0x859baed93ee48e46, -11, 5.09674593842117925320e-04L),
+a8u = LD80C(0xe9f28a4432949af2, -13, 2.23109648015769155122e-04L),
+a9u = LD80C(0xd12ad0d9b93c6bb0, -14, 9.97387167479808509830e-05L),
+a10u= LD80C(0xb7522643c78a219b, -15, 4.37071076331030136818e-05L),
+a11u= LD80C(0xca024dcdece2cb79, -16, 2.40813493372040143061e-05L),
+a12u= LD80C(0xbb90fb6968ebdbf9, -19, 2.79495621083634031729e-06L),
+a13u= LD80C(0xba1c9ffeeae07b37, -17, 1.10931287015513924136e-05L);
+#define a0 (a0u.e)
+#define a1 (a1u.e)
+#define a2 (a2u.e)
+#define a3 (a3u.e)
+#define a4 (a4u.e)
+#define a5 (a5u.e)
+#define a6 (a6u.e)
+#define a7 (a7u.e)
+#define a8 (a8u.e)
+#define a9 (a9u.e)
+#define a10 (a10u.e)
+#define a11 (a11u.e)
+#define a12 (a12u.e)
+#define a13 (a13u.e)
+/*
+ * Domain x in [tc-0.24, tc+0.28], range ~[-6.1205e-22, 6.1205e-22]:
+ * |(lgamma(x) - tf) - t(x - tc)| < 2**-70.5
+ */
+static const union IEEEl2bits
+tcu = LD80C(0xbb16c31ab5f1fb71, 0, 1.46163214496836234128e+00L),
+tfu = LD80C(0xf8cdcde61c520e0f, -4, -1.21486290535849608093e-01L),
+ttu = LD80C(0xd46ee54b27d4de99, -69, -2.81152980996018785880e-21L),
+t0u = LD80C(0x80b9406556a62a6b, -68, 3.40728634996055147231e-21L),
+t1u = LD80C(0xc7e9c6f6df3f8c39, -67, -1.05833162742737073665e-20L),
+t2u = LD80C(0xf7b95e4771c55d51, -2, 4.83836122723810583532e-01L),
+t3u = LD80C(0x97213c6e35e119ff, -3, -1.47587722994530691476e-01L),
+t4u = LD80C(0x845a14a6a81dc94b, -4, 6.46249402389135358063e-02L),
+t5u = LD80C(0x864d46fa89997796, -5, -3.27885410884846056084e-02L),
+t6u = LD80C(0x93373cbd00297438, -6, 1.79706751150707171293e-02L),
+t7u = LD80C(0xa8fcfca7eddc8d1d, -7, -1.03142230361450732547e-02L),
+t8u = LD80C(0xc7e7015ff4bc45af, -8, 6.10053603296546099193e-03L),
+t9u = LD80C(0xf178d2247adc5093, -9, -3.68456964904901200152e-03L),
+t10u = LD80C(0x94188d58f12e5e9f, -9, 2.25976420273774583089e-03L),
+t11u = LD80C(0xb7cbaef14e1406f1, -10, -1.40224943666225639823e-03L),
+t12u = LD80C(0xe63a671e6704ea4d, -11, 8.78250640744776944887e-04L),
+t13u = LD80C(0x914b6c9cae61783e, -11, -5.54255012657716808811e-04L),
+t14u = LD80C(0xb858f5bdb79276fe, -12, 3.51614951536825927370e-04L),
+t15u = LD80C(0xea73e744c34b9591, -13, -2.23591563824520112236e-04L),
+t16u = LD80C(0x99aeabb0d67ba835, -13, 1.46562869351659194136e-04L),
+t17u = LD80C(0xd7c6938325db2024, -14, -1.02889866046435680588e-04L),
+t18u = LD80C(0xe24cb1e3b0474775, -15, 5.39540265505221957652e-05L);
+#define tc (tcu.e)
+#define tf (tfu.e)
+#define tt (ttu.e)
+#define t0 (t0u.e)
+#define t1 (t1u.e)
+#define t2 (t2u.e)
+#define t3 (t3u.e)
+#define t4 (t4u.e)
+#define t5 (t5u.e)
+#define t6 (t6u.e)
+#define t7 (t7u.e)
+#define t8 (t8u.e)
+#define t9 (t9u.e)
+#define t10 (t10u.e)
+#define t11 (t11u.e)
+#define t12 (t12u.e)
+#define t13 (t13u.e)
+#define t14 (t14u.e)
+#define t15 (t15u.e)
+#define t16 (t16u.e)
+#define t17 (t17u.e)
+#define t18 (t18u.e)
+/*
+ * Domain y in [-0.1, 0.232], range ~[-8.1938e-22, 8.3815e-22]:
+ * |(lgamma(1 + y) + 0.5 * y) / y - u(y) / v(y)| < 2**-71.2
+ */
+static const union IEEEl2bits
+u0u = LD80C(0x9e233f1bed863d27, -4, -7.72156649015328606095e-02L),
+u1u = LD80C(0x98280ee45e4ddd3d, -1, 5.94361239198682739769e-01L),
+u2u = LD80C(0xe330c8ead4130733, 0, 1.77492629495841234275e+00L),
+u3u = LD80C(0xd4a213f1a002ec52, 0, 1.66119622514818078064e+00L),
+u4u = LD80C(0xa5a9ca6f5bc62163, -1, 6.47122051417476492989e-01L),
+u5u = LD80C(0xc980e49cd5b019e6, -4, 9.83903751718671509455e-02L),
+u6u = LD80C(0xff636a8bdce7025b, -9, 3.89691687802305743450e-03L),
+v1u = LD80C(0xbd109c533a19fbf5, 1, 2.95413883330948556544e+00L),
+v2u = LD80C(0xd295cbf96f31f099, 1, 3.29039286955665403176e+00L),
+v3u = LD80C(0xdab8bcfee40496cb, 0, 1.70876276441416471410e+00L),
+v4u = LD80C(0xd2f2dc3638567e9f, -2, 4.12009126299534668571e-01L),
+v5u = LD80C(0xa07d9b0851070f41, -5, 3.91822868305682491442e-02L),
+v6u = LD80C(0xe3cd8318f7adb2c4, -11, 8.68998648222144351114e-04L);
+#define u0 (u0u.e)
+#define u1 (u1u.e)
+#define u2 (u2u.e)
+#define u3 (u3u.e)
+#define u4 (u4u.e)
+#define u5 (u5u.e)
+#define u6 (u6u.e)
+#define v1 (v1u.e)
+#define v2 (v2u.e)
+#define v3 (v3u.e)
+#define v4 (v4u.e)
+#define v5 (v5u.e)
+#define v6 (v6u.e)
+/*
+ * Domain x in (2, 3], range ~[-3.3648e-22, 3.4416e-22]:
+ * |(lgamma(y+2) - 0.5 * y) / y - s(y)/r(y)| < 2**-72.3
+ * with y = x - 2.
+ */
+static const union IEEEl2bits
+s0u = LD80C(0x9e233f1bed863d27, -4, -7.72156649015328606095e-02L),
+s1u = LD80C(0xd3ff0dcc7fa91f94, -3, 2.07027640921219389860e-01L),
+s2u = LD80C(0xb2bb62782478ef31, -2, 3.49085881391362090549e-01L),
+s3u = LD80C(0xb49f7438c4611a74, -3, 1.76389518704213357954e-01L),
+s4u = LD80C(0x9a957008fa27ecf9, -5, 3.77401710862930008071e-02L),
+s5u = LD80C(0xda9b389a6ca7a7ac, -9, 3.33566791452943399399e-03L),
+s6u = LD80C(0xbc7a2263faf59c14, -14, 8.98728786745638844395e-05L),
+r1u = LD80C(0xbf5cff5b11477d4d, 0, 1.49502555796294337722e+00L),
+r2u = LD80C(0xd9aec89de08e3da6, -1, 8.50323236984473285866e-01L),
+r3u = LD80C(0xeab7ae5057c443f9, -3, 2.29216312078225806131e-01L),
+r4u = LD80C(0xf29707d9bd2b1e37, -6, 2.96130326586640089145e-02L),
+r5u = LD80C(0xd376c2f09736c5a3, -10, 1.61334161411590662495e-03L),
+r6u = LD80C(0xc985983d0cd34e3d, -16, 2.40232770710953450636e-05L),
+r7u = LD80C(0xe5c7a4f7fc2ef13d, -25, -5.34997929289167573510e-08L);
+#define s0 (s0u.e)
+#define s1 (s1u.e)
+#define s2 (s2u.e)
+#define s3 (s3u.e)
+#define s4 (s4u.e)
+#define s5 (s5u.e)
+#define s6 (s6u.e)
+#define r1 (r1u.e)
+#define r2 (r2u.e)
+#define r3 (r3u.e)
+#define r4 (r4u.e)
+#define r5 (r5u.e)
+#define r6 (r6u.e)
+#define r7 (r7u.e)
+/*
+ * Domain z in [8, 0x1p70], range ~[-3.0235e-22, 3.0563e-22]:
+ * |lgamma(x) - (x - 0.5) * (log(x) - 1) - w(1/x)| < 2**-71.7
+ */
+static const union IEEEl2bits
+w0u = LD80C(0xd67f1c864beb4a69, -2, 4.18938533204672741776e-01L),
+w1u = LD80C(0xaaaaaaaaaaaaaaa1, -4, 8.33333333333333332678e-02L),
+w2u = LD80C(0xb60b60b60b5491c9, -9, -2.77777777777760927870e-03L),
+w3u = LD80C(0xd00d00cf58aede4c, -11, 7.93650793490637233668e-04L),
+w4u = LD80C(0x9c09bf626783d4a5, -11, -5.95238023926039051268e-04L),
+w5u = LD80C(0xdca7cadc5baa517b, -11, 8.41733700408000822962e-04L),
+w6u = LD80C(0xfb060e361e1ffd07, -10, -1.91515849570245136604e-03L),
+w7u = LD80C(0xcbd5101bb58d1f2b, -8, 6.22046743903262649294e-03L),
+w8u = LD80C(0xad27a668d32c821b, -6, -2.11370706734662081843e-02L);
+#define w0 (w0u.e)
+#define w1 (w1u.e)
+#define w2 (w2u.e)
+#define w3 (w3u.e)
+#define w4 (w4u.e)
+#define w5 (w5u.e)
+#define w6 (w6u.e)
+#define w7 (w7u.e)
+#define w8 (w8u.e)
+
+static long double
+sin_pil(long double x)
+{
+ volatile long double vz;
+ long double y,z;
+ uint64_t n;
+ uint16_t hx;
+
+ y = -x;
+
+ vz = y+0x1p63;
+ z = vz-0x1p63;
+ if (z == y)
+ return zero;
+
+ vz = y+0x1p61;
+ EXTRACT_LDBL80_WORDS(hx,n,vz);
+ z = vz-0x1p61;
+ if (z > y) {
+ z -= 0.25; /* adjust to round down */
+ n--;
+ }
+ n &= 7; /* octant of y mod 2 */
+ y = y - z + n * 0.25; /* y mod 2 */
+
+ switch (n) {
+ case 0: y = __kernel_sinl(pi*y,zero,0); break;
+ case 1:
+ case 2: y = __kernel_cosl(pi*(0.5-y),zero); break;
+ case 3:
+ case 4: y = __kernel_sinl(pi*(one-y),zero,0); break;
+ case 5:
+ case 6: y = -__kernel_cosl(pi*(y-1.5),zero); break;
+ default: y = __kernel_sinl(pi*(y-2.0),zero,0); break;
+ }
+ return -y;
+}
+
+long double
+lgammal_r(long double x, int *signgamp)
+{
+ long double nadj,p,p1,p2,p3,q,r,t,w,y,z;
+ uint64_t lx;
+ int i;
+ uint16_t hx,ix;
+
+ EXTRACT_LDBL80_WORDS(hx,lx,x);
+
+ /* purge +-Inf and NaNs */
+ *signgamp = 1;
+ ix = hx&0x7fff;
+ if(ix==0x7fff) return x*x;
+
+ ENTERI();
+
+ /* purge +-0 and tiny arguments */
+ *signgamp = 1-2*(hx>>15);
+ if(ix<0x3fff-67) { /* |x|<2**-(p+3), return -log(|x|) */
+ if((ix|lx)==0)
+ RETURNI(one/vzero);
+ RETURNI(-logl(fabsl(x)));
+ }
+
+ /* purge negative integers and start evaluation for other x < 0 */
+ if(hx&0x8000) {
+ *signgamp = 1;
+ if(ix>=0x3fff+63) /* |x|>=2**(p-1), must be -integer */
+ RETURNI(one/vzero);
+ t = sin_pil(x);
+ if(t==zero) RETURNI(one/vzero); /* -integer */
+ nadj = logl(pi/fabsl(t*x));
+ if(t<zero) *signgamp = -1;
+ x = -x;
+ }
+
+ /* purge 1 and 2 */
+ if((ix==0x3fff || ix==0x4000) && lx==0x8000000000000000ULL) r = 0;
+ /* for x < 2.0 */
+ else if(ix<0x4000) {
+ /*
+ * XXX Supposedly, one can use the following information to replace the
+ * XXX FP rational expressions. A similar approach is appropriate
+ * XXX for ld128, but one (may need?) needs to consider llx, too.
+ *
+ * 8.9999961853027344e-01 3ffe e666600000000000
+ * 7.3159980773925781e-01 3ffe bb4a200000000000
+ * 2.3163998126983643e-01 3ffc ed33080000000000
+ * 1.7316312789916992e+00 3fff dda6180000000000
+ * 1.2316322326660156e+00 3fff 9da6200000000000
+ */
+ if(x<8.9999961853027344e-01) {
+ r = -logl(x);
+ if(x>=7.3159980773925781e-01) {y = 1-x; i= 0;}
+ else if(x>=2.3163998126983643e-01) {y= x-(tc-1); i=1;}
+ else {y = x; i=2;}
+ } else {
+ r = 0;
+ if(x>=1.7316312789916992e+00) {y=2-x;i=0;}
+ else if(x>=1.2316322326660156e+00) {y=x-tc;i=1;}
+ else {y=x-1;i=2;}
+ }
+ switch(i) {
+ case 0:
+ z = y*y;
+ p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*(a10+z*a12)))));
+ p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*(a11+z*a13))))));
+ p = y*p1+p2;
+ r += p-y/2; break;
+ case 1:
+ p = t0+y*t1+tt+y*y*(t2+y*(t3+y*(t4+y*(t5+y*(t6+y*(t7+y*(t8+
+ y*(t9+y*(t10+y*(t11+y*(t12+y*(t13+y*(t14+y*(t15+y*(t16+
+ y*(t17+y*t18))))))))))))))));
+ r += tf + p; break;
+ case 2:
+ p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*(u5+y*u6))))));
+ p2 = 1+y*(v1+y*(v2+y*(v3+y*(v4+y*(v5+y*v6)))));
+ r += p1/p2-y/2;
+ }
+ }
+ /* x < 8.0 */
+ else if(ix<0x4002) {
+ i = x;
+ y = x-i;
+ p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+ q = 1+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*(r6+y*r7))))));
+ r = y/2+p/q;
+ z = 1; /* lgamma(1+s) = log(s) + lgamma(s) */
+ switch(i) {
+ case 7: z *= (y+6); /* FALLTHRU */
+ case 6: z *= (y+5); /* FALLTHRU */
+ case 5: z *= (y+4); /* FALLTHRU */
+ case 4: z *= (y+3); /* FALLTHRU */
+ case 3: z *= (y+2); /* FALLTHRU */
+ r += logl(z); break;
+ }
+ /* 8.0 <= x < 2**(p+3) */
+ } else if (ix<0x3fff+67) {
+ t = logl(x);
+ z = one/x;
+ y = z*z;
+ w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*(w6+y*(w7+y*w8)))))));
+ r = (x-half)*(t-one)+w;
+ /* 2**(p+3) <= x <= inf */
+ } else
+ r = x*(logl(x)-1);
+ if(hx&0x8000) r = nadj - r;
+ RETURNI(r);
+}
Property changes on: trunk/lib/msun/ld80/e_lgammal_r.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/lib/msun/ld80/e_rem_pio2l.h
===================================================================
--- trunk/lib/msun/ld80/e_rem_pio2l.h 2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/e_rem_pio2l.h 2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/* From: @(#)e_rem_pio2.c 1.4 95/01/18 */
/*
* ====================================================
@@ -14,7 +15,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/e_rem_pio2l.h 223262 2011-06-18 13:56:33Z benl $");
/* ld80 version of __ieee754_rem_pio2l(x,y)
*
Modified: trunk/lib/msun/ld80/invtrig.c
===================================================================
--- trunk/lib/msun/ld80/invtrig.c 2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/invtrig.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2008 David Schultz <das at FreeBSD.ORG>
* All rights reserved.
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/invtrig.c 181074 2008-07-31 22:41:26Z das $");
#include "invtrig.h"
Modified: trunk/lib/msun/ld80/invtrig.h
===================================================================
--- trunk/lib/msun/ld80/invtrig.h 2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/invtrig.h 2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2008 David Schultz <das at FreeBSD.ORG>
* All rights reserved.
@@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/msun/ld80/invtrig.h 181152 2008-08-02 03:56:22Z das $
*/
#include <float.h>
Modified: trunk/lib/msun/ld80/k_cosl.c
===================================================================
--- trunk/lib/msun/ld80/k_cosl.c 2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/k_cosl.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/* From: @(#)k_cos.c 1.3 95/01/18 */
/*
* ====================================================
@@ -12,7 +13,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/k_cosl.c 176357 2008-02-17 07:32:14Z das $");
/*
* ld80 version of k_cos.c. See ../src/k_cos.c for most comments.
Added: trunk/lib/msun/ld80/k_expl.h
===================================================================
--- trunk/lib/msun/ld80/k_expl.h (rev 0)
+++ trunk/lib/msun/ld80/k_expl.h 2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,306 @@
+/* $MidnightBSD$ */
+/* from: FreeBSD: head/lib/msun/ld80/s_expl.c 251343 2013-06-03 19:51:32Z kargl */
+
+/*-
+ * Copyright (c) 2009-2013 Steven G. Kargl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Optimized by Bruce D. Evans.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/k_expl.h 284810 2015-06-25 13:01:10Z tijl $");
+
+/*
+ * See s_expl.c for more comments about __k_expl().
+ *
+ * See ../src/e_exp.c and ../src/k_exp.h for precision-independent comments
+ * about the secondary kernels.
+ */
+
+#define INTERVALS 128
+#define LOG2_INTERVALS 7
+#define BIAS (LDBL_MAX_EXP - 1)
+
+static const double
+/*
+ * ln2/INTERVALS = L1+L2 (hi+lo decomposition for multiplication). L1 must
+ * have at least 22 (= log2(|LDBL_MIN_EXP-extras|) + log2(INTERVALS)) lowest
+ * bits zero so that multiplication of it by n is exact.
+ */
+INV_L = 1.8466496523378731e+2, /* 0x171547652b82fe.0p-45 */
+L1 = 5.4152123484527692e-3, /* 0x162e42ff000000.0p-60 */
+L2 = -3.2819649005320973e-13, /* -0x1718432a1b0e26.0p-94 */
+/*
+ * Domain [-0.002708, 0.002708], range ~[-5.7136e-24, 5.7110e-24]:
+ * |exp(x) - p(x)| < 2**-77.2
+ * (0.002708 is ln2/(2*INTERVALS) rounded up a little).
+ */
+A2 = 0.5,
+A3 = 1.6666666666666119e-1, /* 0x15555555555490.0p-55 */
+A4 = 4.1666666666665887e-2, /* 0x155555555554e5.0p-57 */
+A5 = 8.3333354987869413e-3, /* 0x1111115b789919.0p-59 */
+A6 = 1.3888891738560272e-3; /* 0x16c16c651633ae.0p-62 */
+
+/*
+ * 2^(i/INTERVALS) for i in [0,INTERVALS] is represented by two values where
+ * the first 53 bits of the significand are stored in hi and the next 53
+ * bits are in lo. Tang's paper states that the trailing 6 bits of hi must
+ * be zero for his algorithm in both single and double precision, because
+ * the table is re-used in the implementation of expm1() where a floating
+ * point addition involving hi must be exact. Here hi is double, so
+ * converting it to long double gives 11 trailing zero bits.
+ */
+static const struct {
+ double hi;
+ double lo;
+} tbl[INTERVALS] = {
+ 0x1p+0, 0x0p+0,
+ /*
+ * XXX hi is rounded down, and the formatting is not quite normal.
+ * But I rather like both. The 0x1.*p format is good for 4N+1
+ * mantissa bits. Rounding down makes the lo terms positive,
+ * so that the columnar formatting can be simpler.
+ */
+ 0x1.0163da9fb3335p+0, 0x1.b61299ab8cdb7p-54,
+ 0x1.02c9a3e778060p+0, 0x1.dcdef95949ef4p-53,
+ 0x1.04315e86e7f84p+0, 0x1.7ae71f3441b49p-53,
+ 0x1.059b0d3158574p+0, 0x1.d73e2a475b465p-55,
+ 0x1.0706b29ddf6ddp+0, 0x1.8db880753b0f6p-53,
+ 0x1.0874518759bc8p+0, 0x1.186be4bb284ffp-57,
+ 0x1.09e3ecac6f383p+0, 0x1.1487818316136p-54,
+ 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc610bp-54,
+ 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f71p-54,
+ 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c57b53p-59,
+ 0x1.0fb66affed31ap+0, 0x1.e464123bb1428p-53,
+ 0x1.11301d0125b50p+0, 0x1.49d77e35db263p-53,
+ 0x1.12abdc06c31cbp+0, 0x1.f72575a649ad2p-53,
+ 0x1.1429aaea92ddfp+0, 0x1.66820328764b1p-53,
+ 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeab0ap-55,
+ 0x1.172b83c7d517ap+0, 0x1.b9bef918a1d63p-53,
+ 0x1.18af9388c8de9p+0, 0x1.777ee1734784ap-53,
+ 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4968e4p-55,
+ 0x1.1bbe084045cd3p+0, 0x1.3563ce56884fcp-53,
+ 0x1.1d4873168b9aap+0, 0x1.e016e00a2643cp-54,
+ 0x1.1ed5022fcd91cp+0, 0x1.71033fec2243ap-53,
+ 0x1.2063b88628cd6p+0, 0x1.dc775814a8495p-55,
+ 0x1.21f49917ddc96p+0, 0x1.2a97e9494a5eep-55,
+ 0x1.2387a6e756238p+0, 0x1.9b07eb6c70573p-54,
+ 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f4a4p-55,
+ 0x1.26b4565e27cddp+0, 0x1.2bd339940e9d9p-55,
+ 0x1.284dfe1f56380p+0, 0x1.2d9e2b9e07941p-53,
+ 0x1.29e9df51fdee1p+0, 0x1.612e8afad1255p-55,
+ 0x1.2b87fd0dad98fp+0, 0x1.fbbd48ca71f95p-53,
+ 0x1.2d285a6e4030bp+0, 0x1.0024754db41d5p-54,
+ 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d52383p-56,
+ 0x1.306fe0a31b715p+0, 0x1.6f46ad23182e4p-55,
+ 0x1.32170fc4cd831p+0, 0x1.a9ce78e18047cp-55,
+ 0x1.33c08b26416ffp+0, 0x1.32721843659a6p-54,
+ 0x1.356c55f929ff0p+0, 0x1.928c468ec6e76p-53,
+ 0x1.371a7373aa9cap+0, 0x1.4e28aa05e8a8fp-53,
+ 0x1.38cae6d05d865p+0, 0x1.0b53961b37da2p-53,
+ 0x1.3a7db34e59ff6p+0, 0x1.d43792533c144p-53,
+ 0x1.3c32dc313a8e4p+0, 0x1.08003e4516b1ep-53,
+ 0x1.3dea64c123422p+0, 0x1.ada0911f09ebcp-55,
+ 0x1.3fa4504ac801bp+0, 0x1.417ee03548306p-53,
+ 0x1.4160a21f72e29p+0, 0x1.f0864b71e7b6cp-53,
+ 0x1.431f5d950a896p+0, 0x1.b8e088728219ap-53,
+ 0x1.44e086061892dp+0, 0x1.89b7a04ef80d0p-59,
+ 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a76p-54,
+ 0x1.486a2b5c13cd0p+0, 0x1.3c1a3b69062f0p-56,
+ 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be56p-54,
+ 0x1.4bfdad5362a27p+0, 0x1.d4397afec42e2p-56,
+ 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a7833p-54,
+ 0x1.4f9b2769d2ca6p+0, 0x1.5a67b16d3540ep-53,
+ 0x1.516daa2cf6641p+0, 0x1.8225ea5909b04p-53,
+ 0x1.5342b569d4f81p+0, 0x1.be1507893b0d5p-53,
+ 0x1.551a4ca5d920ep+0, 0x1.8a5d8c4048699p-53,
+ 0x1.56f4736b527dap+0, 0x1.9bb2c011d93adp-54,
+ 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1de8p-55,
+ 0x1.5ab07dd485429p+0, 0x1.6324c054647adp-54,
+ 0x1.5c9268a5946b7p+0, 0x1.c4b1b816986a2p-60,
+ 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e65ep-54,
+ 0x1.605e1b976dc08p+0, 0x1.60edeb25490dcp-53,
+ 0x1.6247eb03a5584p+0, 0x1.63e1f40dfa5b5p-53,
+ 0x1.6434634ccc31fp+0, 0x1.8edf0e2989db3p-53,
+ 0x1.6623882552224p+0, 0x1.224fb3c5371e6p-53,
+ 0x1.68155d44ca973p+0, 0x1.038ae44f73e65p-57,
+ 0x1.6a09e667f3bccp+0, 0x1.21165f626cdd5p-53,
+ 0x1.6c012750bdabep+0, 0x1.daed533001e9ep-53,
+ 0x1.6dfb23c651a2ep+0, 0x1.e441c597c3775p-53,
+ 0x1.6ff7df9519483p+0, 0x1.9f0fc369e7c42p-53,
+ 0x1.71f75e8ec5f73p+0, 0x1.ba46e1e5de15ap-53,
+ 0x1.73f9a48a58173p+0, 0x1.7ab9349cd1562p-53,
+ 0x1.75feb564267c8p+0, 0x1.7edd354674916p-53,
+ 0x1.780694fde5d3fp+0, 0x1.866b80a02162dp-54,
+ 0x1.7a11473eb0186p+0, 0x1.afaa2047ed9b4p-53,
+ 0x1.7c1ed0130c132p+0, 0x1.f124cd1164dd6p-54,
+ 0x1.7e2f336cf4e62p+0, 0x1.05d02ba15797ep-56,
+ 0x1.80427543e1a11p+0, 0x1.6c1bccec9346bp-53,
+ 0x1.82589994cce12p+0, 0x1.159f115f56694p-53,
+ 0x1.8471a4623c7acp+0, 0x1.9ca5ed72f8c81p-53,
+ 0x1.868d99b4492ecp+0, 0x1.01c83b21584a3p-53,
+ 0x1.88ac7d98a6699p+0, 0x1.994c2f37cb53ap-54,
+ 0x1.8ace5422aa0dbp+0, 0x1.6e9f156864b27p-54,
+ 0x1.8cf3216b5448bp+0, 0x1.de55439a2c38bp-53,
+ 0x1.8f1ae99157736p+0, 0x1.5cc13a2e3976cp-55,
+ 0x1.9145b0b91ffc5p+0, 0x1.114c368d3ed6ep-53,
+ 0x1.93737b0cdc5e4p+0, 0x1.e8a0387e4a814p-53,
+ 0x1.95a44cbc8520ep+0, 0x1.d36906d2b41f9p-53,
+ 0x1.97d829fde4e4fp+0, 0x1.173d241f23d18p-53,
+ 0x1.9a0f170ca07b9p+0, 0x1.7462137188ce7p-53,
+ 0x1.9c49182a3f090p+0, 0x1.c7c46b071f2bep-56,
+ 0x1.9e86319e32323p+0, 0x1.824ca78e64c6ep-56,
+ 0x1.a0c667b5de564p+0, 0x1.6535b51719567p-53,
+ 0x1.a309bec4a2d33p+0, 0x1.6305c7ddc36abp-54,
+ 0x1.a5503b23e255cp+0, 0x1.1684892395f0fp-53,
+ 0x1.a799e1330b358p+0, 0x1.bcb7ecac563c7p-54,
+ 0x1.a9e6b5579fdbfp+0, 0x1.0fac90ef7fd31p-54,
+ 0x1.ac36bbfd3f379p+0, 0x1.81b72cd4624ccp-53,
+ 0x1.ae89f995ad3adp+0, 0x1.7a1cd345dcc81p-54,
+ 0x1.b0e07298db665p+0, 0x1.2108559bf8deep-53,
+ 0x1.b33a2b84f15fap+0, 0x1.ed7fa1cf7b290p-53,
+ 0x1.b59728de55939p+0, 0x1.1c7102222c90ep-53,
+ 0x1.b7f76f2fb5e46p+0, 0x1.d54f610356a79p-53,
+ 0x1.ba5b030a10649p+0, 0x1.0819678d5eb69p-53,
+ 0x1.bcc1e904bc1d2p+0, 0x1.23dd07a2d9e84p-55,
+ 0x1.bf2c25bd71e08p+0, 0x1.0811ae04a31c7p-53,
+ 0x1.c199bdd85529cp+0, 0x1.11065895048ddp-55,
+ 0x1.c40ab5fffd07ap+0, 0x1.b4537e083c60ap-54,
+ 0x1.c67f12e57d14bp+0, 0x1.2884dff483cadp-54,
+ 0x1.c8f6d9406e7b5p+0, 0x1.1acbc48805c44p-56,
+ 0x1.cb720dcef9069p+0, 0x1.503cbd1e949dbp-56,
+ 0x1.cdf0b555dc3f9p+0, 0x1.889f12b1f58a3p-53,
+ 0x1.d072d4a07897bp+0, 0x1.1a1e45e4342b2p-53,
+ 0x1.d2f87080d89f1p+0, 0x1.15bc247313d44p-53,
+ 0x1.d5818dcfba487p+0, 0x1.2ed02d75b3707p-55,
+ 0x1.d80e316c98397p+0, 0x1.7709f3a09100cp-53,
+ 0x1.da9e603db3285p+0, 0x1.c2300696db532p-54,
+ 0x1.dd321f301b460p+0, 0x1.2da5778f018c3p-54,
+ 0x1.dfc97337b9b5ep+0, 0x1.72d195873da52p-53,
+ 0x1.e264614f5a128p+0, 0x1.424ec3f42f5b5p-53,
+ 0x1.e502ee78b3ff6p+0, 0x1.39e8980a9cc8fp-55,
+ 0x1.e7a51fbc74c83p+0, 0x1.2d522ca0c8de2p-54,
+ 0x1.ea4afa2a490d9p+0, 0x1.0b1ee7431ebb6p-53,
+ 0x1.ecf482d8e67f0p+0, 0x1.1b60625f7293ap-53,
+ 0x1.efa1bee615a27p+0, 0x1.dc7f486a4b6b0p-54,
+ 0x1.f252b376bba97p+0, 0x1.3a1a5bf0d8e43p-54,
+ 0x1.f50765b6e4540p+0, 0x1.9d3e12dd8a18bp-54,
+ 0x1.f7bfdad9cbe13p+0, 0x1.1227697fce57bp-53,
+ 0x1.fa7c1819e90d8p+0, 0x1.74853f3a5931ep-55,
+ 0x1.fd3c22b8f71f1p+0, 0x1.2eb74966579e7p-57
+};
+
+/*
+ * Kernel for expl(x). x must be finite and not tiny or huge.
+ * "tiny" is anything that would make us underflow (|A6*x^6| < ~LDBL_MIN).
+ * "huge" is anything that would make fn*L1 inexact (|x| > ~2**17*ln2).
+ */
+static inline void
+__k_expl(long double x, long double *hip, long double *lop, int *kp)
+{
+ long double fn, q, r, r1, r2, t, z;
+ int n, n2;
+
+ /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */
+ /* Use a specialized rint() to get fn. Assume round-to-nearest. */
+ fn = x * INV_L + 0x1.8p63 - 0x1.8p63;
+ r = x - fn * L1 - fn * L2; /* r = r1 + r2 done independently. */
+#if defined(HAVE_EFFICIENT_IRINTL)
+ n = irintl(fn);
+#elif defined(HAVE_EFFICIENT_IRINT)
+ n = irint(fn);
+#else
+ n = (int)fn;
+#endif
+ n2 = (unsigned)n % INTERVALS;
+ /* Depend on the sign bit being propagated: */
+ *kp = n >> LOG2_INTERVALS;
+ r1 = x - fn * L1;
+ r2 = fn * -L2;
+
+ /* Evaluate expl(endpoint[n2] + r1 + r2) = tbl[n2] * expl(r1 + r2). */
+ z = r * r;
+#if 0
+ q = r2 + z * (A2 + r * A3) + z * z * (A4 + r * A5) + z * z * z * A6;
+#else
+ q = r2 + z * A2 + z * r * (A3 + r * A4 + z * (A5 + r * A6));
+#endif
+ t = (long double)tbl[n2].lo + tbl[n2].hi;
+ *hip = tbl[n2].hi;
+ *lop = tbl[n2].lo + t * (q + r1);
+}
+
+static inline void
+k_hexpl(long double x, long double *hip, long double *lop)
+{
+ float twopkm1;
+ int k;
+
+ __k_expl(x, hip, lop, &k);
+ SET_FLOAT_WORD(twopkm1, 0x3f800000 + ((k - 1) << 23));
+ *hip *= twopkm1;
+ *lop *= twopkm1;
+}
+
+static inline long double
+hexpl(long double x)
+{
+ long double hi, lo, twopkm2;
+ int k;
+
+ twopkm2 = 1;
+ __k_expl(x, &hi, &lo, &k);
+ SET_LDBL_EXPSIGN(twopkm2, BIAS + k - 2);
+ return (lo + hi) * 2 * twopkm2;
+}
+
+#ifdef _COMPLEX_H
+/*
+ * See ../src/k_exp.c for details.
+ */
+static inline long double complex
+__ldexp_cexpl(long double complex z, int expt)
+{
+ long double exp_x, hi, lo;
+ long double x, y, scale1, scale2;
+ int half_expt, k;
+
+ x = creall(z);
+ y = cimagl(z);
+ __k_expl(x, &hi, &lo, &k);
+
+ exp_x = (lo + hi) * 0x1p16382;
+ expt += k - 16382;
+
+ scale1 = 1;
+ half_expt = expt / 2;
+ SET_LDBL_EXPSIGN(scale1, BIAS + half_expt);
+ scale2 = 1;
+ SET_LDBL_EXPSIGN(scale1, BIAS + expt - half_expt);
+
+ return (CMPLXL(cos(y) * exp_x * scale1 * scale2,
+ sinl(y) * exp_x * scale1 * scale2));
+}
+#endif /* _COMPLEX_H */
Property changes on: trunk/lib/msun/ld80/k_expl.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/lib/msun/ld80/k_sinl.c
===================================================================
--- trunk/lib/msun/ld80/k_sinl.c 2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/k_sinl.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/* From: @(#)k_sin.c 1.3 95/01/18 */
/*
* ====================================================
@@ -12,7 +13,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/k_sinl.c 176357 2008-02-17 07:32:14Z das $");
/*
* ld80 version of k_sin.c. See ../src/k_sin.c for most comments.
Modified: trunk/lib/msun/ld80/k_tanl.c
===================================================================
--- trunk/lib/msun/ld80/k_tanl.c 2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/k_tanl.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/* From: @(#)k_tan.c 1.5 04/04/22 SMI */
/*
@@ -12,7 +13,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/k_tanl.c 176387 2008-02-18 15:39:52Z bde $");
/*
* ld80 version of k_tan.c. See ../src/k_tan.c for most comments.
Added: trunk/lib/msun/ld80/s_erfl.c
===================================================================
--- trunk/lib/msun/ld80/s_erfl.c (rev 0)
+++ trunk/lib/msun/ld80/s_erfl.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,338 @@
+/* $MidnightBSD$ */
+/* @(#)s_erf.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/s_erfl.c 271779 2014-09-18 15:10:22Z tijl $");
+
+/*
+ * See s_erf.c for complete comments.
+ *
+ * Converted to long double by Steven G. Kargl.
+ */
+#include <float.h>
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
+#include "math.h"
+#include "math_private.h"
+
+/* XXX Prevent compilers from erroneously constant folding: */
+static const volatile long double tiny = 0x1p-10000L;
+
+static const double
+half= 0.5,
+one = 1,
+two = 2;
+/*
+ * In the domain [0, 2**-34], only the first term in the power series
+ * expansion of erf(x) is used. The magnitude of the first neglected
+ * terms is less than 2**-102.
+ */
+static const union IEEEl2bits
+efxu = LD80C(0x8375d410a6db446c, -3, 1.28379167095512573902e-1L),
+efx8u = LD80C(0x8375d410a6db446c, 0, 1.02703333676410059122e+0L),
+/*
+ * Domain [0, 0.84375], range ~[-1.423e-22, 1.423e-22]:
+ * |(erf(x) - x)/x - pp(x)/qq(x)| < 2**-72.573
+ */
+pp0u = LD80C(0x8375d410a6db446c, -3, 1.28379167095512573902e-1L),
+pp1u = LD80C(0xa46c7d09ec3d0cec, -2, -3.21140201054840180596e-1L),
+pp2u = LD80C(0x9b31e66325576f86, -5, -3.78893851760347812082e-2L),
+pp3u = LD80C(0x804ac72c9a0b97dd, -7, -7.83032847030604679616e-3L),
+pp4u = LD80C(0x9f42bcbc3d5a601d, -12, -3.03765663857082048459e-4L),
+pp5u = LD80C(0x9ec4ad6193470693, -16, -1.89266527398167917502e-5L),
+qq1u = LD80C(0xdb4b8eb713188d6b, -2, 4.28310832832310510579e-1L),
+qq2u = LD80C(0xa5750835b2459bd1, -4, 8.07896272074540216658e-2L),
+qq3u = LD80C(0x8b85d6bd6a90b51c, -7, 8.51579638189385354266e-3L),
+qq4u = LD80C(0x87332f82cff4ff96, -11, 5.15746855583604912827e-4L),
+qq5u = LD80C(0x83466cb6bf9dca00, -16, 1.56492109706256700009e-5L),
+qq6u = LD80C(0xf5bf98c2f996bf63, -24, 1.14435527803073879724e-7L);
+#define efx (efxu.e)
+#define efx8 (efx8u.e)
+#define pp0 (pp0u.e)
+#define pp1 (pp1u.e)
+#define pp2 (pp2u.e)
+#define pp3 (pp3u.e)
+#define pp4 (pp4u.e)
+#define pp5 (pp5u.e)
+#define qq1 (qq1u.e)
+#define qq2 (qq2u.e)
+#define qq3 (qq3u.e)
+#define qq4 (qq4u.e)
+#define qq5 (qq5u.e)
+#define qq6 (qq6u.e)
+static const union IEEEl2bits
+erxu = LD80C(0xd7bb3d0000000000, -1, 8.42700779438018798828e-1L),
+/*
+ * Domain [0.84375, 1.25], range ~[-8.132e-22, 8.113e-22]:
+ * |(erf(x) - erx) - pa(x)/qa(x)| < 2**-71.762
+ */
+pa0u = LD80C(0xe8211158da02c692, -27, 1.35116960705131296711e-8L),
+pa1u = LD80C(0xd488f89f36988618, -2, 4.15107507167065612570e-1L),
+pa2u = LD80C(0xece74f8c63fa3942, -4, -1.15675565215949226989e-1L),
+pa3u = LD80C(0xc8d31e020727c006, -4, 9.80589241379624665791e-2L),
+pa4u = LD80C(0x985d5d5fafb0551f, -5, 3.71984145558422368847e-2L),
+pa5u = LD80C(0xa5b6c4854d2f5452, -8, -5.05718799340957673661e-3L),
+pa6u = LD80C(0x85c8d58fe3993a47, -8, 4.08277919612202243721e-3L),
+pa7u = LD80C(0xddbfbc23677b35cf, -13, 2.11476292145347530794e-4L),
+qa1u = LD80C(0xb8a977896f5eff3f, -1, 7.21335860303380361298e-1L),
+qa2u = LD80C(0x9fcd662c3d4eac86, -1, 6.24227891731886593333e-1L),
+qa3u = LD80C(0x9d0b618eac67ba07, -2, 3.06727455774491855801e-1L),
+qa4u = LD80C(0x881a4293f6d6c92d, -3, 1.32912674218195890535e-1L),
+qa5u = LD80C(0xbab144f07dea45bf, -5, 4.55792134233613027584e-2L),
+qa6u = LD80C(0xa6c34ba438bdc900, -7, 1.01783980070527682680e-2L),
+qa7u = LD80C(0x8fa866dc20717a91, -9, 2.19204436518951438183e-3L);
+#define erx (erxu.e)
+#define pa0 (pa0u.e)
+#define pa1 (pa1u.e)
+#define pa2 (pa2u.e)
+#define pa3 (pa3u.e)
+#define pa4 (pa4u.e)
+#define pa5 (pa5u.e)
+#define pa6 (pa6u.e)
+#define pa7 (pa7u.e)
+#define qa1 (qa1u.e)
+#define qa2 (qa2u.e)
+#define qa3 (qa3u.e)
+#define qa4 (qa4u.e)
+#define qa5 (qa5u.e)
+#define qa6 (qa6u.e)
+#define qa7 (qa7u.e)
+static const union IEEEl2bits
+/*
+ * Domain [1.25,2.85715], range ~[-2.334e-22,2.334e-22]:
+ * |log(x*erfc(x)) + x**2 + 0.5625 - ra(x)/sa(x)| < 2**-71.860
+ */
+ra0u = LD80C(0xa1a091e0fb4f335a, -7, -9.86494298915814308249e-3L),
+ra1u = LD80C(0xc2b0d045ae37df6b, -1, -7.60510460864878271275e-1L),
+ra2u = LD80C(0xf2cec3ee7da636c5, 3, -1.51754798236892278250e+1L),
+ra3u = LD80C(0x813cc205395adc7d, 7, -1.29237335516455333420e+2L),
+ra4u = LD80C(0x8737c8b7b4062c2f, 9, -5.40871625829510494776e+2L),
+ra5u = LD80C(0x8ffe5383c08d4943, 10, -1.15194769466026108551e+3L),
+ra6u = LD80C(0x983573e64d5015a9, 10, -1.21767039790249025544e+3L),
+ra7u = LD80C(0x92a794e763a6d4db, 9, -5.86618463370624636688e+2L),
+ra8u = LD80C(0xd5ad1fae77c3d9a3, 6, -1.06838132335777049840e+2L),
+ra9u = LD80C(0x934c1a247807bb9c, 2, -4.60303980944467334806e+0L),
+sa1u = LD80C(0xd342f90012bb1189, 4, 2.64077014928547064865e+1L),
+sa2u = LD80C(0x839be13d9d5da883, 8, 2.63217811300123973067e+2L),
+sa3u = LD80C(0x9f8cba6d1ae1b24b, 10, 1.27639775710344617587e+3L),
+sa4u = LD80C(0xcaa83f403713e33e, 11, 3.24251544209971162003e+3L),
+sa5u = LD80C(0x8796aff2f3c47968, 12, 4.33883591261332837874e+3L),
+sa6u = LD80C(0xb6ef97f9c753157b, 11, 2.92697460344182158454e+3L),
+sa7u = LD80C(0xe02aee5f83773d1c, 9, 8.96670799139389559818e+2L),
+sa8u = LD80C(0xc82b83855b88e07e, 6, 1.00084987800048510018e+2L),
+sa9u = LD80C(0x92f030aefadf28ad, 1, 2.29591004455459083843e+0L);
+#define ra0 (ra0u.e)
+#define ra1 (ra1u.e)
+#define ra2 (ra2u.e)
+#define ra3 (ra3u.e)
+#define ra4 (ra4u.e)
+#define ra5 (ra5u.e)
+#define ra6 (ra6u.e)
+#define ra7 (ra7u.e)
+#define ra8 (ra8u.e)
+#define ra9 (ra9u.e)
+#define sa1 (sa1u.e)
+#define sa2 (sa2u.e)
+#define sa3 (sa3u.e)
+#define sa4 (sa4u.e)
+#define sa5 (sa5u.e)
+#define sa6 (sa6u.e)
+#define sa7 (sa7u.e)
+#define sa8 (sa8u.e)
+#define sa9 (sa9u.e)
+/*
+ * Domain [2.85715,7], range ~[-8.323e-22,8.390e-22]:
+ * |log(x*erfc(x)) + x**2 + 0.5625 - rb(x)/sb(x)| < 2**-70.326
+ */
+static const union IEEEl2bits
+rb0u = LD80C(0xa1a091cf43abcd26, -7, -9.86494292470284646962e-3L),
+rb1u = LD80C(0xd19d2df1cbb8da0a, -1, -8.18804618389296662837e-1L),
+rb2u = LD80C(0x9a4dd1383e5daf5b, 4, -1.92879967111618594779e+1L),
+rb3u = LD80C(0xbff0ae9fc0751de6, 7, -1.91940164551245394969e+2L),
+rb4u = LD80C(0xdde08465310b472b, 9, -8.87508080766577324539e+2L),
+rb5u = LD80C(0xe796e1d38c8c70a9, 10, -1.85271506669474503781e+3L),
+rb6u = LD80C(0xbaf655a76e0ab3b5, 10, -1.49569795581333675349e+3L),
+rb7u = LD80C(0x95d21e3e75503c21, 8, -2.99641547972948019157e+2L),
+sb1u = LD80C(0x814487ed823c8cbd, 5, 3.23169247732868256569e+1L),
+sb2u = LD80C(0xbe4bfbb1301304be, 8, 3.80593618534539961773e+2L),
+sb3u = LD80C(0x809c4ade46b927c7, 11, 2.05776827838541292848e+3L),
+sb4u = LD80C(0xa55284359f3395a8, 12, 5.29031455540062116327e+3L),
+sb5u = LD80C(0xbcfa72da9b820874, 12, 6.04730608102312640462e+3L),
+sb6u = LD80C(0x9d09a35988934631, 11, 2.51260238030767176221e+3L),
+sb7u = LD80C(0xd675bbe542c159fa, 7, 2.14459898308561015684e+2L);
+#define rb0 (rb0u.e)
+#define rb1 (rb1u.e)
+#define rb2 (rb2u.e)
+#define rb3 (rb3u.e)
+#define rb4 (rb4u.e)
+#define rb5 (rb5u.e)
+#define rb6 (rb6u.e)
+#define rb7 (rb7u.e)
+#define sb1 (sb1u.e)
+#define sb2 (sb2u.e)
+#define sb3 (sb3u.e)
+#define sb4 (sb4u.e)
+#define sb5 (sb5u.e)
+#define sb6 (sb6u.e)
+#define sb7 (sb7u.e)
+/*
+ * Domain [7,108], range ~[-4.422e-22,4.422e-22]:
+ * |log(x*erfc(x)) + x**2 + 0.5625 - rc(x)/sc(x)| < 2**-70.938
+ */
+static const union IEEEl2bits
+/* err = -4.422092275318925082e-22 -70.937689 */
+rc0u = LD80C(0xa1a091cf437a17ad, -7, -9.86494292470008707260e-3L),
+rc1u = LD80C(0xbe79c5a978122b00, -1, -7.44045595049165939261e-1L),
+rc2u = LD80C(0xdb26f9bbe31a2794, 3, -1.36970155085888424425e+1L),
+rc3u = LD80C(0xb5f69a38f5747ac8, 6, -9.09816453742625888546e+1L),
+rc4u = LD80C(0xd79676d970d0a21a, 7, -2.15587750997584074147e+2L),
+rc5u = LD80C(0xfe528153c45ec97c, 6, -1.27161142938347796666e+2L),
+sc1u = LD80C(0xc5e8cd46d5604a96, 4, 2.47386727842204312937e+1L),
+sc2u = LD80C(0xc5f0f5a5484520eb, 7, 1.97941248254913378865e+2L),
+sc3u = LD80C(0x964e3c7b34db9170, 9, 6.01222441484087787522e+2L),
+sc4u = LD80C(0x99be1b89faa0596a, 9, 6.14970430845978077827e+2L),
+sc5u = LD80C(0xf80dfcbf37ffc5ea, 6, 1.24027318931184605891e+2L);
+#define rc0 (rc0u.e)
+#define rc1 (rc1u.e)
+#define rc2 (rc2u.e)
+#define rc3 (rc3u.e)
+#define rc4 (rc4u.e)
+#define rc5 (rc5u.e)
+#define sc1 (sc1u.e)
+#define sc2 (sc2u.e)
+#define sc3 (sc3u.e)
+#define sc4 (sc4u.e)
+#define sc5 (sc5u.e)
+
+long double
+erfl(long double x)
+{
+ long double ax,R,S,P,Q,s,y,z,r;
+ uint64_t lx;
+ int32_t i;
+ uint16_t hx;
+
+ EXTRACT_LDBL80_WORDS(hx, lx, x);
+
+ if((hx & 0x7fff) == 0x7fff) { /* erfl(nan)=nan */
+ i = (hx>>15)<<1;
+ return (1-i)+one/x; /* erfl(+-inf)=+-1 */
+ }
+
+ ENTERI();
+
+ ax = fabsl(x);
+ if(ax < 0.84375) {
+ if(ax < 0x1p-34L) {
+ if(ax < 0x1p-16373L)
+ RETURNI((8*x+efx8*x)/8); /* avoid spurious underflow */
+ RETURNI(x + efx*x);
+ }
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*(pp4+z*pp5))));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*(qq5+z*qq6)))));
+ y = r/s;
+ RETURNI(x + x*y);
+ }
+ if(ax < 1.25) {
+ s = ax-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*(pa6+s*pa7))))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*(qa6+s*qa7))))));
+ if(x>=0) RETURNI(erx + P/Q); else RETURNI(-erx - P/Q);
+ }
+ if(ax >= 7) { /* inf>|x|>= 7 */
+ if(x>=0) RETURNI(one-tiny); else RETURNI(tiny-one);
+ }
+ s = one/(ax*ax);
+ if(ax < 2.85715) { /* |x| < 2.85715 */
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*(ra7+
+ s*(ra8+s*ra9))))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+
+ s*(sa8+s*sa9))))))));
+ } else { /* |x| >= 2.85715 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*(rb6+s*rb7))))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7))))));
+ }
+ z=(float)ax;
+ r=expl(-z*z-0.5625)*expl((z-ax)*(z+ax)+R/S);
+ if(x>=0) RETURNI(one-r/ax); else RETURNI(r/ax-one);
+}
+
+long double
+erfcl(long double x)
+{
+ long double ax,R,S,P,Q,s,y,z,r;
+ uint64_t lx;
+ uint16_t hx;
+
+ EXTRACT_LDBL80_WORDS(hx, lx, x);
+
+ if((hx & 0x7fff) == 0x7fff) { /* erfcl(nan)=nan */
+ /* erfcl(+-inf)=0,2 */
+ return ((hx>>15)<<1)+one/x;
+ }
+
+ ENTERI();
+
+ ax = fabsl(x);
+ if(ax < 0.84375L) {
+ if(ax < 0x1p-34L)
+ RETURNI(one-x);
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*(pp4+z*pp5))));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*(qq5+z*qq6)))));
+ y = r/s;
+ if(ax < 0.25L) { /* x<1/4 */
+ RETURNI(one-(x+x*y));
+ } else {
+ r = x*y;
+ r += (x-half);
+ RETURNI(half - r);
+ }
+ }
+ if(ax < 1.25L) {
+ s = ax-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*(pa6+s*pa7))))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*(qa6+s*qa7))))));
+ if(x>=0) {
+ z = one-erx; RETURNI(z - P/Q);
+ } else {
+ z = (erx+P/Q); RETURNI(one+z);
+ }
+ }
+
+ if(ax < 108) { /* |x| < 108 */
+ s = one/(ax*ax);
+ if(ax < 2.85715) { /* |x| < 2.85715 */
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*(ra7+
+ s*(ra8+s*ra9))))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+
+ s*(sa8+s*sa9))))))));
+ } else if(ax < 7) { /* | |x| < 7 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*(rb6+s*rb7))))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7))))));
+ } else {
+ if(x < -7) RETURNI(two-tiny);/* x < -7 */
+ R=rc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*rc5))));
+ S=one+s*(sc1+s*(sc2+s*(sc3+s*(sc4+s*sc5))));
+ }
+ z = (float)ax;
+ r = expl(-z*z-0.5625)*expl((z-ax)*(z+ax)+R/S);
+ if(x>0) RETURNI(r/ax); else RETURNI(two-r/ax);
+ } else {
+ if(x>0) RETURNI(tiny*tiny); else RETURNI(two-tiny);
+ }
+}
Property changes on: trunk/lib/msun/ld80/s_erfl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/lib/msun/ld80/s_exp2l.c
===================================================================
--- trunk/lib/msun/ld80/s_exp2l.c 2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/s_exp2l.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2005-2008 David Schultz <das at FreeBSD.ORG>
* All rights reserved.
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/s_exp2l.c 251046 2013-05-27 22:45:05Z kargl $");
#include <float.h>
#include <stdint.h>
@@ -36,28 +37,31 @@
#include "fpmath.h"
#include "math.h"
+#include "math_private.h"
#define TBLBITS 7
#define TBLSIZE (1 << TBLBITS)
#define BIAS (LDBL_MAX_EXP - 1)
-#define EXPMASK (BIAS + LDBL_MAX_EXP)
-static const long double huge = 0x1p10000L;
-#if 0 /* XXX Prevent gcc from erroneously constant folding this. */
-static const long double twom10000 = 0x1p-10000L;
-#else
-static volatile long double twom10000 = 0x1p-10000L;
-#endif
+static volatile long double
+ huge = 0x1p10000L,
+ twom10000 = 0x1p-10000L;
+static const union IEEEl2bits
+P1 = LD80C(0xb17217f7d1cf79ac, -1, 6.93147180559945309429e-1L);
+
static const double
- redux = 0x1.8p63 / TBLSIZE,
- P1 = 0x1.62e42fefa39efp-1,
- P2 = 0x1.ebfbdff82c58fp-3,
- P3 = 0x1.c6b08d7049fap-5,
- P4 = 0x1.3b2ab6fba4da5p-7,
- P5 = 0x1.5d8804780a736p-10,
- P6 = 0x1.430918835e33dp-13;
+redux = 0x1.8p63 / TBLSIZE,
+/*
+ * Domain [-0.00390625, 0.00390625], range ~[-1.7079e-23, 1.7079e-23]
+ * |exp(x) - p(x)| < 2**-75.6
+ */
+P2 = 2.4022650695910072e-1, /* 0x1ebfbdff82c58f.0p-55 */
+P3 = 5.5504108664816879e-2, /* 0x1c6b08d7049e1a.0p-57 */
+P4 = 9.6181291055695180e-3, /* 0x13b2ab6fa8321a.0p-59 */
+P5 = 1.3333563089183052e-3, /* 0x15d8806f67f251.0p-62 */
+P6 = 1.5413361552277414e-4; /* 0x1433ddacff3441.0p-65 */
static const double tbl[TBLSIZE * 2] = {
0x1.6a09e667f3bcdp-1, -0x1.bdd3413b2648p-55,
@@ -190,8 +194,8 @@
0x1.68155d44ca973p+0, 0x1.038ae44f74p-57,
};
-/*
- * exp2l(x): compute the base 2 exponential of x
+/**
+ * Compute the base 2 exponential of x for Intel 80-bit format.
*
* Accuracy: Peak error < 0.511 ulp.
*
@@ -207,7 +211,7 @@
* with |z| <= 2**-(TBLBITS+1).
*
* We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
- * degree-6 minimax polynomial with maximum error under 2**-69.
+ * degree-6 minimax polynomial with maximum error under 2**-75.6.
* The table entries each have 104 bits of accuracy, encoded as
* a pair of double precision values.
*/
@@ -222,30 +226,22 @@
/* Filter out exceptional cases. */
u.e = x;
hx = u.xbits.expsign;
- ix = hx & EXPMASK;
+ ix = hx & 0x7fff;
if (ix >= BIAS + 14) { /* |x| >= 16384 or x is NaN */
if (ix == BIAS + LDBL_MAX_EXP) {
- if (u.xbits.man != 1ULL << 63 || (hx & 0x8000) == 0)
- return (x + x); /* x is +Inf or NaN */
- else
- return (0.0); /* x is -Inf */
+ if (hx & 0x8000 && u.xbits.man == 1ULL << 63)
+ return (0.0L); /* x is -Inf */
+ return (x + x); /* x is +Inf, NaN or unsupported */
}
if (x >= 16384)
return (huge * huge); /* overflow */
if (x <= -16446)
return (twom10000 * twom10000); /* underflow */
- } else if (ix <= BIAS - 66) { /* |x| < 0x1p-66 */
- return (1.0 + x);
+ } else if (ix <= BIAS - 66) { /* |x| < 0x1p-65 (includes pseudos) */
+ return (1.0L + x); /* 1 with inexact */
}
-#ifdef __i386__
- /*
- * The default precision on i386 is 53 bits, so long doubles are
- * broken. Call exp2() to get an accurate (double precision) result.
- */
- if (fpgetprec() != FP_PE)
- return (exp2(x));
-#endif
+ ENTERI();
/*
* Reduce x, computing z, i0, and k. The low bits of x + redux
@@ -269,10 +265,10 @@
z = x - u.e;
v.xbits.man = 1ULL << 63;
if (k >= LDBL_MIN_EXP) {
- v.xbits.expsign = LDBL_MAX_EXP - 1 + k;
+ v.xbits.expsign = BIAS + k;
twopk = v.e;
} else {
- v.xbits.expsign = LDBL_MAX_EXP - 1 + k + 10000;
+ v.xbits.expsign = BIAS + k + 10000;
twopkp10000 = v.e;
}
@@ -279,16 +275,15 @@
/* Compute r = exp2l(y) = exp2lt[i0] * p(z). */
long double t_hi = tbl[i0];
long double t_lo = tbl[i0 + 1];
- /* XXX This gives > 1 ulp errors outside of FE_TONEAREST mode */
- r = t_lo + (t_hi + t_lo) * z * (P1 + z * (P2 + z * (P3 + z * (P4
+ r = t_lo + (t_hi + t_lo) * z * (P1.e + z * (P2 + z * (P3 + z * (P4
+ z * (P5 + z * P6))))) + t_hi;
/* Scale by 2**k. */
if (k >= LDBL_MIN_EXP) {
if (k == LDBL_MAX_EXP)
- return (r * 2.0 * 0x1p16383L);
- return (r * twopk);
+ RETURNI(r * 2.0 * 0x1p16383L);
+ RETURNI(r * twopk);
} else {
- return (r * twopkp10000 * twom10000);
+ RETURNI(r * twopkp10000 * twom10000);
}
}
Added: trunk/lib/msun/ld80/s_expl.c
===================================================================
--- trunk/lib/msun/ld80/s_expl.c (rev 0)
+++ trunk/lib/msun/ld80/s_expl.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,285 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009-2013 Steven G. Kargl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Optimized by Bruce D. Evans.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/s_expl.c 271779 2014-09-18 15:10:22Z tijl $");
+
+/**
+ * Compute the exponential of x for Intel 80-bit format. This is based on:
+ *
+ * PTP Tang, "Table-driven implementation of the exponential function
+ * in IEEE floating-point arithmetic," ACM Trans. Math. Soft., 15,
+ * 144-157 (1989).
+ *
+ * where the 32 table entries have been expanded to INTERVALS (see below).
+ */
+
+#include <float.h>
+
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
+#include "math.h"
+#include "math_private.h"
+#include "k_expl.h"
+
+/* XXX Prevent compilers from erroneously constant folding these: */
+static const volatile long double
+huge = 0x1p10000L,
+tiny = 0x1p-10000L;
+
+static const long double
+twom10000 = 0x1p-10000L;
+
+static const union IEEEl2bits
+/* log(2**16384 - 0.5) rounded towards zero: */
+/* log(2**16384 - 0.5 + 1) rounded towards zero for expm1l() is the same: */
+o_thresholdu = LD80C(0xb17217f7d1cf79ab, 13, 11356.5234062941439488L),
+#define o_threshold (o_thresholdu.e)
+/* log(2**(-16381-64-1)) rounded towards zero: */
+u_thresholdu = LD80C(0xb21dfe7f09e2baa9, 13, -11399.4985314888605581L);
+#define u_threshold (u_thresholdu.e)
+
+long double
+expl(long double x)
+{
+ union IEEEl2bits u;
+ long double hi, lo, t, twopk;
+ int k;
+ uint16_t hx, ix;
+
+ DOPRINT_START(&x);
+
+ /* Filter out exceptional cases. */
+ u.e = x;
+ hx = u.xbits.expsign;
+ ix = hx & 0x7fff;
+ if (ix >= BIAS + 13) { /* |x| >= 8192 or x is NaN */
+ if (ix == BIAS + LDBL_MAX_EXP) {
+ if (hx & 0x8000) /* x is -Inf, -NaN or unsupported */
+ RETURNP(-1 / x);
+ RETURNP(x + x); /* x is +Inf, +NaN or unsupported */
+ }
+ if (x > o_threshold)
+ RETURNP(huge * huge);
+ if (x < u_threshold)
+ RETURNP(tiny * tiny);
+ } else if (ix < BIAS - 75) { /* |x| < 0x1p-75 (includes pseudos) */
+ RETURN2P(1, x); /* 1 with inexact iff x != 0 */
+ }
+
+ ENTERI();
+
+ twopk = 1;
+ __k_expl(x, &hi, &lo, &k);
+ t = SUM2P(hi, lo);
+
+ /* Scale by 2**k. */
+ if (k >= LDBL_MIN_EXP) {
+ if (k == LDBL_MAX_EXP)
+ RETURNI(t * 2 * 0x1p16383L);
+ SET_LDBL_EXPSIGN(twopk, BIAS + k);
+ RETURNI(t * twopk);
+ } else {
+ SET_LDBL_EXPSIGN(twopk, BIAS + k + 10000);
+ RETURNI(t * twopk * twom10000);
+ }
+}
+
+/**
+ * Compute expm1l(x) for Intel 80-bit format. This is based on:
+ *
+ * PTP Tang, "Table-driven implementation of the Expm1 function
+ * in IEEE floating-point arithmetic," ACM Trans. Math. Soft., 18,
+ * 211-222 (1992).
+ */
+
+/*
+ * Our T1 and T2 are chosen to be approximately the points where method
+ * A and method B have the same accuracy. Tang's T1 and T2 are the
+ * points where method A's accuracy changes by a full bit. For Tang,
+ * this drop in accuracy makes method A immediately less accurate than
+ * method B, but our larger INTERVALS makes method A 2 bits more
+ * accurate so it remains the most accurate method significantly
+ * closer to the origin despite losing the full bit in our extended
+ * range for it.
+ */
+static const double
+T1 = -0.1659, /* ~-30.625/128 * log(2) */
+T2 = 0.1659; /* ~30.625/128 * log(2) */
+
+/*
+ * Domain [-0.1659, 0.1659], range ~[-2.6155e-22, 2.5507e-23]:
+ * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-71.6
+ *
+ * XXX the coeffs aren't very carefully rounded, and I get 2.8 more bits,
+ * but unlike for ld128 we can't drop any terms.
+ */
+static const union IEEEl2bits
+B3 = LD80C(0xaaaaaaaaaaaaaaab, -3, 1.66666666666666666671e-1L),
+B4 = LD80C(0xaaaaaaaaaaaaaaac, -5, 4.16666666666666666712e-2L);
+
+static const double
+B5 = 8.3333333333333245e-3, /* 0x1.111111111110cp-7 */
+B6 = 1.3888888888888861e-3, /* 0x1.6c16c16c16c0ap-10 */
+B7 = 1.9841269841532042e-4, /* 0x1.a01a01a0319f9p-13 */
+B8 = 2.4801587302069236e-5, /* 0x1.a01a01a03cbbcp-16 */
+B9 = 2.7557316558468562e-6, /* 0x1.71de37fd33d67p-19 */
+B10 = 2.7557315829785151e-7, /* 0x1.27e4f91418144p-22 */
+B11 = 2.5063168199779829e-8, /* 0x1.ae94fabdc6b27p-26 */
+B12 = 2.0887164654459567e-9; /* 0x1.1f122d6413fe1p-29 */
+
+long double
+expm1l(long double x)
+{
+ union IEEEl2bits u, v;
+ long double fn, hx2_hi, hx2_lo, q, r, r1, r2, t, twomk, twopk, x_hi;
+ long double x_lo, x2, z;
+ long double x4;
+ int k, n, n2;
+ uint16_t hx, ix;
+
+ DOPRINT_START(&x);
+
+ /* Filter out exceptional cases. */
+ u.e = x;
+ hx = u.xbits.expsign;
+ ix = hx & 0x7fff;
+ if (ix >= BIAS + 6) { /* |x| >= 64 or x is NaN */
+ if (ix == BIAS + LDBL_MAX_EXP) {
+ if (hx & 0x8000) /* x is -Inf, -NaN or unsupported */
+ RETURNP(-1 / x - 1);
+ RETURNP(x + x); /* x is +Inf, +NaN or unsupported */
+ }
+ if (x > o_threshold)
+ RETURNP(huge * huge);
+ /*
+ * expm1l() never underflows, but it must avoid
+ * unrepresentable large negative exponents. We used a
+ * much smaller threshold for large |x| above than in
+ * expl() so as to handle not so large negative exponents
+ * in the same way as large ones here.
+ */
+ if (hx & 0x8000) /* x <= -64 */
+ RETURN2P(tiny, -1); /* good for x < -65ln2 - eps */
+ }
+
+ ENTERI();
+
+ if (T1 < x && x < T2) {
+ if (ix < BIAS - 74) { /* |x| < 0x1p-74 (includes pseudos) */
+ /* x (rounded) with inexact if x != 0: */
+ RETURNPI(x == 0 ? x :
+ (0x1p100 * x + fabsl(x)) * 0x1p-100);
+ }
+
+ x2 = x * x;
+ x4 = x2 * x2;
+ q = x4 * (x2 * (x4 *
+ /*
+ * XXX the number of terms is no longer good for
+ * pairwise grouping of all except B3, and the
+ * grouping is no longer from highest down.
+ */
+ (x2 * B12 + (x * B11 + B10)) +
+ (x2 * (x * B9 + B8) + (x * B7 + B6))) +
+ (x * B5 + B4.e)) + x2 * x * B3.e;
+
+ x_hi = (float)x;
+ x_lo = x - x_hi;
+ hx2_hi = x_hi * x_hi / 2;
+ hx2_lo = x_lo * (x + x_hi) / 2;
+ if (ix >= BIAS - 7)
+ RETURN2PI(hx2_hi + x_hi, hx2_lo + x_lo + q);
+ else
+ RETURN2PI(x, hx2_lo + q + hx2_hi);
+ }
+
+ /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */
+ /* Use a specialized rint() to get fn. Assume round-to-nearest. */
+ fn = x * INV_L + 0x1.8p63 - 0x1.8p63;
+#if defined(HAVE_EFFICIENT_IRINTL)
+ n = irintl(fn);
+#elif defined(HAVE_EFFICIENT_IRINT)
+ n = irint(fn);
+#else
+ n = (int)fn;
+#endif
+ n2 = (unsigned)n % INTERVALS;
+ k = n >> LOG2_INTERVALS;
+ r1 = x - fn * L1;
+ r2 = fn * -L2;
+ r = r1 + r2;
+
+ /* Prepare scale factor. */
+ v.e = 1;
+ v.xbits.expsign = BIAS + k;
+ twopk = v.e;
+
+ /*
+ * Evaluate lower terms of
+ * expl(endpoint[n2] + r1 + r2) = tbl[n2] * expl(r1 + r2).
+ */
+ z = r * r;
+ q = r2 + z * (A2 + r * A3) + z * z * (A4 + r * A5) + z * z * z * A6;
+
+ t = (long double)tbl[n2].lo + tbl[n2].hi;
+
+ if (k == 0) {
+ t = SUM2P(tbl[n2].hi - 1, tbl[n2].lo * (r1 + 1) + t * q +
+ tbl[n2].hi * r1);
+ RETURNI(t);
+ }
+ if (k == -1) {
+ t = SUM2P(tbl[n2].hi - 2, tbl[n2].lo * (r1 + 1) + t * q +
+ tbl[n2].hi * r1);
+ RETURNI(t / 2);
+ }
+ if (k < -7) {
+ t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1));
+ RETURNI(t * twopk - 1);
+ }
+ if (k > 2 * LDBL_MANT_DIG - 1) {
+ t = SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1));
+ if (k == LDBL_MAX_EXP)
+ RETURNI(t * 2 * 0x1p16383L - 1);
+ RETURNI(t * twopk - 1);
+ }
+
+ v.xbits.expsign = BIAS - k;
+ twomk = v.e;
+
+ if (k > LDBL_MANT_DIG - 1)
+ t = SUM2P(tbl[n2].hi, tbl[n2].lo - twomk + t * (q + r1));
+ else
+ t = SUM2P(tbl[n2].hi - twomk, tbl[n2].lo + t * (q + r1));
+ RETURNI(t * twopk);
+}
Property changes on: trunk/lib/msun/ld80/s_expl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/lib/msun/ld80/s_logl.c
===================================================================
--- trunk/lib/msun/ld80/s_logl.c (rev 0)
+++ trunk/lib/msun/ld80/s_logl.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -0,0 +1,718 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2007-2013 Bruce D. Evans
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/msun/ld80/s_logl.c 251292 2013-06-03 09:14:31Z das $");
+
+/**
+ * Implementation of the natural logarithm of x for Intel 80-bit format.
+ *
+ * First decompose x into its base 2 representation:
+ *
+ * log(x) = log(X * 2**k), where X is in [1, 2)
+ * = log(X) + k * log(2).
+ *
+ * Let X = X_i + e, where X_i is the center of one of the intervals
+ * [-1.0/256, 1.0/256), [1.0/256, 3.0/256), .... [2.0-1.0/256, 2.0+1.0/256)
+ * and X is in this interval. Then
+ *
+ * log(X) = log(X_i + e)
+ * = log(X_i * (1 + e / X_i))
+ * = log(X_i) + log(1 + e / X_i).
+ *
+ * The values log(X_i) are tabulated below. Let d = e / X_i and use
+ *
+ * log(1 + d) = p(d)
+ *
+ * where p(d) = d - 0.5*d*d + ... is a special minimax polynomial of
+ * suitably high degree.
+ *
+ * To get sufficiently small roundoff errors, k * log(2), log(X_i), and
+ * sometimes (if |k| is not large) the first term in p(d) must be evaluated
+ * and added up in extra precision. Extra precision is not needed for the
+ * rest of p(d). In the worst case when k = 0 and log(X_i) is 0, the final
+ * error is controlled mainly by the error in the second term in p(d). The
+ * error in this term itself is at most 0.5 ulps from the d*d operation in
+ * it. The error in this term relative to the first term is thus at most
+ * 0.5 * |-0.5| * |d| < 1.0/1024 ulps. We aim for an accumulated error of
+ * at most twice this at the point of the final rounding step. Thus the
+ * final error should be at most 0.5 + 1.0/512 = 0.5020 ulps. Exhaustive
+ * testing of a float variant of this function showed a maximum final error
+ * of 0.5008 ulps. Non-exhaustive testing of a double variant of this
+ * function showed a maximum final error of 0.5078 ulps (near 1+1.0/256).
+ *
+ * We made the maximum of |d| (and thus the total relative error and the
+ * degree of p(d)) small by using a large number of intervals. Using
+ * centers of intervals instead of endpoints reduces this maximum by a
+ * factor of 2 for a given number of intervals. p(d) is special only
+ * in beginning with the Taylor coefficients 0 + 1*d, which tends to happen
+ * naturally. The most accurate minimax polynomial of a given degree might
+ * be different, but then we wouldn't want it since we would have to do
+ * extra work to avoid roundoff error (especially for P0*d instead of d).
+ */
+
+#ifdef DEBUG
+#include <assert.h>
+#include <fenv.h>
+#endif
+
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
+#include "math.h"
+#define i386_SSE_GOOD
+#ifndef NO_STRUCT_RETURN
+#define STRUCT_RETURN
+#endif
+#include "math_private.h"
+
+#if !defined(NO_UTAB) && !defined(NO_UTABL)
+#define USE_UTAB
+#endif
+
+/*
+ * Domain [-0.005280, 0.004838], range ~[-5.1736e-22, 5.1738e-22]:
+ * |log(1 + d)/d - p(d)| < 2**-70.7
+ */
+static const double
+P2 = -0.5,
+P3 = 3.3333333333333359e-1, /* 0x1555555555555a.0p-54 */
+P4 = -2.5000000000004424e-1, /* -0x1000000000031d.0p-54 */
+P5 = 1.9999999992970016e-1, /* 0x1999999972f3c7.0p-55 */
+P6 = -1.6666666072191585e-1, /* -0x15555548912c09.0p-55 */
+P7 = 1.4286227413310518e-1, /* 0x12494f9d9def91.0p-55 */
+P8 = -1.2518388626763144e-1; /* -0x1006068cc0b97c.0p-55 */
+
+static volatile const double zero = 0;
+
+#define INTERVALS 128
+#define LOG2_INTERVALS 7
+#define TSIZE (INTERVALS + 1)
+#define G(i) (T[(i)].G)
+#define F_hi(i) (T[(i)].F_hi)
+#define F_lo(i) (T[(i)].F_lo)
+#define ln2_hi F_hi(TSIZE - 1)
+#define ln2_lo F_lo(TSIZE - 1)
+#define E(i) (U[(i)].E)
+#define H(i) (U[(i)].H)
+
+static const struct {
+ float G; /* 1/(1 + i/128) rounded to 8/9 bits */
+ float F_hi; /* log(1 / G_i) rounded (see below) */
+ double F_lo; /* next 53 bits for log(1 / G_i) */
+} T[TSIZE] = {
+ /*
+ * ln2_hi and each F_hi(i) are rounded to a number of bits that
+ * makes F_hi(i) + dk*ln2_hi exact for all i and all dk.
+ *
+ * The last entry (for X just below 2) is used to define ln2_hi
+ * and ln2_lo, to ensure that F_hi(i) and F_lo(i) cancel exactly
+ * with dk*ln2_hi and dk*ln2_lo, respectively, when dk = -1.
+ * This is needed for accuracy when x is just below 1. (To avoid
+ * special cases, such x are "reduced" strangely to X just below
+ * 2 and dk = -1, and then the exact cancellation is needed
+ * because any the error from any non-exactness would be too
+ * large).
+ *
+ * We want to share this table between double precision and ld80,
+ * so the relevant range of dk is the larger one of ld80
+ * ([-16445, 16383]) and the relevant exactness requirement is
+ * the stricter one of double precision. The maximum number of
+ * bits in F_hi(i) that works is very dependent on i but has
+ * a minimum of 33. We only need about 12 bits in F_hi(i) for
+ * it to provide enough extra precision in double precision (11
+ * more than that are required for ld80).
+ *
+ * We round F_hi(i) to 24 bits so that it can have type float,
+ * mainly to minimize the size of the table. Using all 24 bits
+ * in a float for it automatically satisfies the above constraints.
+ */
+ 0x800000.0p-23, 0, 0,
+ 0xfe0000.0p-24, 0x8080ac.0p-30, -0x14ee431dae6675.0p-84,
+ 0xfc0000.0p-24, 0x8102b3.0p-29, -0x1db29ee2d83718.0p-84,
+ 0xfa0000.0p-24, 0xc24929.0p-29, 0x1191957d173698.0p-83,
+ 0xf80000.0p-24, 0x820aec.0p-28, 0x13ce8888e02e79.0p-82,
+ 0xf60000.0p-24, 0xa33577.0p-28, -0x17a4382ce6eb7c.0p-82,
+ 0xf48000.0p-24, 0xbc42cb.0p-28, -0x172a21161a1076.0p-83,
+ 0xf30000.0p-24, 0xd57797.0p-28, -0x1e09de07cb9589.0p-82,
+ 0xf10000.0p-24, 0xf7518e.0p-28, 0x1ae1eec1b036c5.0p-91,
+ 0xef0000.0p-24, 0x8cb9df.0p-27, -0x1d7355325d560e.0p-81,
+ 0xed8000.0p-24, 0x999ec0.0p-27, -0x1f9f02d256d503.0p-82,
+ 0xec0000.0p-24, 0xa6988b.0p-27, -0x16fc0a9d12c17a.0p-83,
+ 0xea0000.0p-24, 0xb80698.0p-27, 0x15d581c1e8da9a.0p-81,
+ 0xe80000.0p-24, 0xc99af3.0p-27, -0x1535b3ba8f150b.0p-83,
+ 0xe70000.0p-24, 0xd273b2.0p-27, 0x163786f5251af0.0p-85,
+ 0xe50000.0p-24, 0xe442c0.0p-27, 0x1bc4b2368e32d5.0p-84,
+ 0xe38000.0p-24, 0xf1b83f.0p-27, 0x1c6090f684e676.0p-81,
+ 0xe20000.0p-24, 0xff448a.0p-27, -0x1890aa69ac9f42.0p-82,
+ 0xe08000.0p-24, 0x8673f6.0p-26, 0x1b9985194b6b00.0p-80,
+ 0xdf0000.0p-24, 0x8d515c.0p-26, -0x1dc08d61c6ef1e.0p-83,
+ 0xdd8000.0p-24, 0x943a9e.0p-26, -0x1f72a2dac729b4.0p-82,
+ 0xdc0000.0p-24, 0x9b2fe6.0p-26, -0x1fd4dfd3a0afb9.0p-80,
+ 0xda8000.0p-24, 0xa2315d.0p-26, -0x11b26121629c47.0p-82,
+ 0xd90000.0p-24, 0xa93f2f.0p-26, 0x1286d633e8e569.0p-81,
+ 0xd78000.0p-24, 0xb05988.0p-26, 0x16128eba936770.0p-84,
+ 0xd60000.0p-24, 0xb78094.0p-26, 0x16ead577390d32.0p-80,
+ 0xd50000.0p-24, 0xbc4c6c.0p-26, 0x151131ccf7c7b7.0p-81,
+ 0xd38000.0p-24, 0xc3890a.0p-26, -0x115e2cd714bd06.0p-80,
+ 0xd20000.0p-24, 0xcad2d7.0p-26, -0x1847f406ebd3b0.0p-82,
+ 0xd10000.0p-24, 0xcfb620.0p-26, 0x1c2259904d6866.0p-81,
+ 0xcf8000.0p-24, 0xd71653.0p-26, 0x1ece57a8d5ae55.0p-80,
+ 0xce0000.0p-24, 0xde843a.0p-26, -0x1f109d4bc45954.0p-81,
+ 0xcd0000.0p-24, 0xe37fde.0p-26, 0x1bc03dc271a74d.0p-81,
+ 0xcb8000.0p-24, 0xeb050c.0p-26, -0x1bf2badc0df842.0p-85,
+ 0xca0000.0p-24, 0xf29878.0p-26, -0x18efededd89fbe.0p-87,
+ 0xc90000.0p-24, 0xf7ad6f.0p-26, 0x1373ff977baa69.0p-81,
+ 0xc80000.0p-24, 0xfcc8e3.0p-26, 0x196766f2fb3283.0p-80,
+ 0xc68000.0p-24, 0x823f30.0p-25, 0x19bd076f7c434e.0p-79,
+ 0xc58000.0p-24, 0x84d52c.0p-25, -0x1a327257af0f46.0p-79,
+ 0xc40000.0p-24, 0x88bc74.0p-25, 0x113f23def19c5a.0p-81,
+ 0xc30000.0p-24, 0x8b5ae6.0p-25, 0x1759f6e6b37de9.0p-79,
+ 0xc20000.0p-24, 0x8dfccb.0p-25, 0x1ad35ca6ed5148.0p-81,
+ 0xc10000.0p-24, 0x90a22b.0p-25, 0x1a1d71a87deba4.0p-79,
+ 0xbf8000.0p-24, 0x94a0d8.0p-25, -0x139e5210c2b731.0p-80,
+ 0xbe8000.0p-24, 0x974f16.0p-25, -0x18f6ebcff3ed73.0p-81,
+ 0xbd8000.0p-24, 0x9a00f1.0p-25, -0x1aa268be39aab7.0p-79,
+ 0xbc8000.0p-24, 0x9cb672.0p-25, -0x14c8815839c566.0p-79,
+ 0xbb0000.0p-24, 0xa0cda1.0p-25, 0x1eaf46390dbb24.0p-81,
+ 0xba0000.0p-24, 0xa38c6e.0p-25, 0x138e20d831f698.0p-81,
+ 0xb90000.0p-24, 0xa64f05.0p-25, -0x1e8d3c41123616.0p-82,
+ 0xb80000.0p-24, 0xa91570.0p-25, 0x1ce28f5f3840b2.0p-80,
+ 0xb70000.0p-24, 0xabdfbb.0p-25, -0x186e5c0a424234.0p-79,
+ 0xb60000.0p-24, 0xaeadef.0p-25, -0x14d41a0b2a08a4.0p-83,
+ 0xb50000.0p-24, 0xb18018.0p-25, 0x16755892770634.0p-79,
+ 0xb40000.0p-24, 0xb45642.0p-25, -0x16395ebe59b152.0p-82,
+ 0xb30000.0p-24, 0xb73077.0p-25, 0x1abc65c8595f09.0p-80,
+ 0xb20000.0p-24, 0xba0ec4.0p-25, -0x1273089d3dad89.0p-79,
+ 0xb10000.0p-24, 0xbcf133.0p-25, 0x10f9f67b1f4bbf.0p-79,
+ 0xb00000.0p-24, 0xbfd7d2.0p-25, -0x109fab90486409.0p-80,
+ 0xaf0000.0p-24, 0xc2c2ac.0p-25, -0x1124680aa43333.0p-79,
+ 0xae8000.0p-24, 0xc439b3.0p-25, -0x1f360cc4710fc0.0p-80,
+ 0xad8000.0p-24, 0xc72afd.0p-25, -0x132d91f21d89c9.0p-80,
+ 0xac8000.0p-24, 0xca20a2.0p-25, -0x16bf9b4d1f8da8.0p-79,
+ 0xab8000.0p-24, 0xcd1aae.0p-25, 0x19deb5ce6a6a87.0p-81,
+ 0xaa8000.0p-24, 0xd0192f.0p-25, 0x1a29fb48f7d3cb.0p-79,
+ 0xaa0000.0p-24, 0xd19a20.0p-25, 0x1127d3c6457f9d.0p-81,
+ 0xa90000.0p-24, 0xd49f6a.0p-25, -0x1ba930e486a0ac.0p-81,
+ 0xa80000.0p-24, 0xd7a94b.0p-25, -0x1b6e645f31549e.0p-79,
+ 0xa70000.0p-24, 0xdab7d0.0p-25, 0x1118a425494b61.0p-80,
+ 0xa68000.0p-24, 0xdc40d5.0p-25, 0x1966f24d29d3a3.0p-80,
+ 0xa58000.0p-24, 0xdf566d.0p-25, -0x1d8e52eb2248f1.0p-82,
+ 0xa48000.0p-24, 0xe270ce.0p-25, -0x1ee370f96e6b68.0p-80,
+ 0xa40000.0p-24, 0xe3ffce.0p-25, 0x1d155324911f57.0p-80,
+ 0xa30000.0p-24, 0xe72179.0p-25, -0x1fe6e2f2f867d9.0p-80,
+ 0xa20000.0p-24, 0xea4812.0p-25, 0x1b7be9add7f4d4.0p-80,
+ 0xa18000.0p-24, 0xebdd3d.0p-25, 0x1b3cfb3f7511dd.0p-79,
+ 0xa08000.0p-24, 0xef0b5b.0p-25, -0x1220de1f730190.0p-79,
+ 0xa00000.0p-24, 0xf0a451.0p-25, -0x176364c9ac81cd.0p-80,
+ 0x9f0000.0p-24, 0xf3da16.0p-25, 0x1eed6b9aafac8d.0p-81,
+ 0x9e8000.0p-24, 0xf576e9.0p-25, 0x1d593218675af2.0p-79,
+ 0x9d8000.0p-24, 0xf8b47c.0p-25, -0x13e8eb7da053e0.0p-84,
+ 0x9d0000.0p-24, 0xfa553f.0p-25, 0x1c063259bcade0.0p-79,
+ 0x9c0000.0p-24, 0xfd9ac5.0p-25, 0x1ef491085fa3c1.0p-79,
+ 0x9b8000.0p-24, 0xff3f8c.0p-25, 0x1d607a7c2b8c53.0p-79,
+ 0x9a8000.0p-24, 0x814697.0p-24, -0x12ad3817004f3f.0p-78,
+ 0x9a0000.0p-24, 0x821b06.0p-24, -0x189fc53117f9e5.0p-81,
+ 0x990000.0p-24, 0x83c5f8.0p-24, 0x14cf15a048907b.0p-79,
+ 0x988000.0p-24, 0x849c7d.0p-24, 0x1cbb1d35fb8287.0p-78,
+ 0x978000.0p-24, 0x864ba6.0p-24, 0x1128639b814f9c.0p-78,
+ 0x970000.0p-24, 0x87244c.0p-24, 0x184733853300f0.0p-79,
+ 0x968000.0p-24, 0x87fdaa.0p-24, 0x109d23aef77dd6.0p-80,
+ 0x958000.0p-24, 0x89b293.0p-24, -0x1a81ef367a59de.0p-78,
+ 0x950000.0p-24, 0x8a8e20.0p-24, -0x121ad3dbb2f452.0p-78,
+ 0x948000.0p-24, 0x8b6a6a.0p-24, -0x1cfb981628af72.0p-79,
+ 0x938000.0p-24, 0x8d253a.0p-24, -0x1d21730ea76cfe.0p-79,
+ 0x930000.0p-24, 0x8e03c2.0p-24, 0x135cc00e566f77.0p-78,
+ 0x928000.0p-24, 0x8ee30d.0p-24, -0x10fcb5df257a26.0p-80,
+ 0x918000.0p-24, 0x90a3ee.0p-24, -0x16e171b15433d7.0p-79,
+ 0x910000.0p-24, 0x918587.0p-24, -0x1d050da07f3237.0p-79,
+ 0x908000.0p-24, 0x9267e7.0p-24, 0x1be03669a5268d.0p-79,
+ 0x8f8000.0p-24, 0x942f04.0p-24, 0x10b28e0e26c337.0p-79,
+ 0x8f0000.0p-24, 0x9513c3.0p-24, 0x1a1d820da57cf3.0p-78,
+ 0x8e8000.0p-24, 0x95f950.0p-24, -0x19ef8f13ae3cf1.0p-79,
+ 0x8e0000.0p-24, 0x96dfab.0p-24, -0x109e417a6e507c.0p-78,
+ 0x8d0000.0p-24, 0x98aed2.0p-24, 0x10d01a2c5b0e98.0p-79,
+ 0x8c8000.0p-24, 0x9997a2.0p-24, -0x1d6a50d4b61ea7.0p-78,
+ 0x8c0000.0p-24, 0x9a8145.0p-24, 0x1b3b190b83f952.0p-78,
+ 0x8b8000.0p-24, 0x9b6bbf.0p-24, 0x13a69fad7e7abe.0p-78,
+ 0x8b0000.0p-24, 0x9c5711.0p-24, -0x11cd12316f576b.0p-78,
+ 0x8a8000.0p-24, 0x9d433b.0p-24, 0x1c95c444b807a2.0p-79,
+ 0x898000.0p-24, 0x9f1e22.0p-24, -0x1b9c224ea698c3.0p-79,
+ 0x890000.0p-24, 0xa00ce1.0p-24, 0x125ca93186cf0f.0p-81,
+ 0x888000.0p-24, 0xa0fc80.0p-24, -0x1ee38a7bc228b3.0p-79,
+ 0x880000.0p-24, 0xa1ed00.0p-24, -0x1a0db876613d20.0p-78,
+ 0x878000.0p-24, 0xa2de62.0p-24, 0x193224e8516c01.0p-79,
+ 0x870000.0p-24, 0xa3d0a9.0p-24, 0x1fa28b4d2541ad.0p-79,
+ 0x868000.0p-24, 0xa4c3d6.0p-24, 0x1c1b5760fb4572.0p-78,
+ 0x858000.0p-24, 0xa6acea.0p-24, 0x1fed5d0f65949c.0p-80,
+ 0x850000.0p-24, 0xa7a2d4.0p-24, 0x1ad270c9d74936.0p-80,
+ 0x848000.0p-24, 0xa899ab.0p-24, 0x199ff15ce53266.0p-79,
+ 0x840000.0p-24, 0xa99171.0p-24, 0x1a19e15ccc45d2.0p-79,
+ 0x838000.0p-24, 0xaa8a28.0p-24, -0x121a14ec532b36.0p-80,
+ 0x830000.0p-24, 0xab83d1.0p-24, 0x1aee319980bff3.0p-79,
+ 0x828000.0p-24, 0xac7e6f.0p-24, -0x18ffd9e3900346.0p-80,
+ 0x820000.0p-24, 0xad7a03.0p-24, -0x1e4db102ce29f8.0p-80,
+ 0x818000.0p-24, 0xae768f.0p-24, 0x17c35c55a04a83.0p-81,
+ 0x810000.0p-24, 0xaf7415.0p-24, 0x1448324047019b.0p-78,
+ 0x808000.0p-24, 0xb07298.0p-24, -0x1750ee3915a198.0p-78,
+ 0x800000.0p-24, 0xb17218.0p-24, -0x105c610ca86c39.0p-81,
+};
+
+#ifdef USE_UTAB
+static const struct {
+ float H; /* 1 + i/INTERVALS (exact) */
+ float E; /* H(i) * G(i) - 1 (exact) */
+} U[TSIZE] = {
+ 0x800000.0p-23, 0,
+ 0x810000.0p-23, -0x800000.0p-37,
+ 0x820000.0p-23, -0x800000.0p-35,
+ 0x830000.0p-23, -0x900000.0p-34,
+ 0x840000.0p-23, -0x800000.0p-33,
+ 0x850000.0p-23, -0xc80000.0p-33,
+ 0x860000.0p-23, -0xa00000.0p-36,
+ 0x870000.0p-23, 0x940000.0p-33,
+ 0x880000.0p-23, 0x800000.0p-35,
+ 0x890000.0p-23, -0xc80000.0p-34,
+ 0x8a0000.0p-23, 0xe00000.0p-36,
+ 0x8b0000.0p-23, 0x900000.0p-33,
+ 0x8c0000.0p-23, -0x800000.0p-35,
+ 0x8d0000.0p-23, -0xe00000.0p-33,
+ 0x8e0000.0p-23, 0x880000.0p-33,
+ 0x8f0000.0p-23, -0xa80000.0p-34,
+ 0x900000.0p-23, -0x800000.0p-35,
+ 0x910000.0p-23, 0x800000.0p-37,
+ 0x920000.0p-23, 0x900000.0p-35,
+ 0x930000.0p-23, 0xd00000.0p-35,
+ 0x940000.0p-23, 0xe00000.0p-35,
+ 0x950000.0p-23, 0xc00000.0p-35,
+ 0x960000.0p-23, 0xe00000.0p-36,
+ 0x970000.0p-23, -0x800000.0p-38,
+ 0x980000.0p-23, -0xc00000.0p-35,
+ 0x990000.0p-23, -0xd00000.0p-34,
+ 0x9a0000.0p-23, 0x880000.0p-33,
+ 0x9b0000.0p-23, 0xe80000.0p-35,
+ 0x9c0000.0p-23, -0x800000.0p-35,
+ 0x9d0000.0p-23, 0xb40000.0p-33,
+ 0x9e0000.0p-23, 0x880000.0p-34,
+ 0x9f0000.0p-23, -0xe00000.0p-35,
+ 0xa00000.0p-23, 0x800000.0p-33,
+ 0xa10000.0p-23, -0x900000.0p-36,
+ 0xa20000.0p-23, -0xb00000.0p-33,
+ 0xa30000.0p-23, -0xa00000.0p-36,
+ 0xa40000.0p-23, 0x800000.0p-33,
+ 0xa50000.0p-23, -0xf80000.0p-35,
+ 0xa60000.0p-23, 0x880000.0p-34,
+ 0xa70000.0p-23, -0x900000.0p-33,
+ 0xa80000.0p-23, -0x800000.0p-35,
+ 0xa90000.0p-23, 0x900000.0p-34,
+ 0xaa0000.0p-23, 0xa80000.0p-33,
+ 0xab0000.0p-23, -0xac0000.0p-34,
+ 0xac0000.0p-23, -0x800000.0p-37,
+ 0xad0000.0p-23, 0xf80000.0p-35,
+ 0xae0000.0p-23, 0xf80000.0p-34,
+ 0xaf0000.0p-23, -0xac0000.0p-33,
+ 0xb00000.0p-23, -0x800000.0p-33,
+ 0xb10000.0p-23, -0xb80000.0p-34,
+ 0xb20000.0p-23, -0x800000.0p-34,
+ 0xb30000.0p-23, -0xb00000.0p-35,
+ 0xb40000.0p-23, -0x800000.0p-35,
+ 0xb50000.0p-23, -0xe00000.0p-36,
+ 0xb60000.0p-23, -0x800000.0p-35,
+ 0xb70000.0p-23, -0xb00000.0p-35,
+ 0xb80000.0p-23, -0x800000.0p-34,
+ 0xb90000.0p-23, -0xb80000.0p-34,
+ 0xba0000.0p-23, -0x800000.0p-33,
+ 0xbb0000.0p-23, -0xac0000.0p-33,
+ 0xbc0000.0p-23, 0x980000.0p-33,
+ 0xbd0000.0p-23, 0xbc0000.0p-34,
+ 0xbe0000.0p-23, 0xe00000.0p-36,
+ 0xbf0000.0p-23, -0xb80000.0p-35,
+ 0xc00000.0p-23, -0x800000.0p-33,
+ 0xc10000.0p-23, 0xa80000.0p-33,
+ 0xc20000.0p-23, 0x900000.0p-34,
+ 0xc30000.0p-23, -0x800000.0p-35,
+ 0xc40000.0p-23, -0x900000.0p-33,
+ 0xc50000.0p-23, 0x820000.0p-33,
+ 0xc60000.0p-23, 0x800000.0p-38,
+ 0xc70000.0p-23, -0x820000.0p-33,
+ 0xc80000.0p-23, 0x800000.0p-33,
+ 0xc90000.0p-23, -0xa00000.0p-36,
+ 0xca0000.0p-23, -0xb00000.0p-33,
+ 0xcb0000.0p-23, 0x840000.0p-34,
+ 0xcc0000.0p-23, -0xd00000.0p-34,
+ 0xcd0000.0p-23, 0x800000.0p-33,
+ 0xce0000.0p-23, -0xe00000.0p-35,
+ 0xcf0000.0p-23, 0xa60000.0p-33,
+ 0xd00000.0p-23, -0x800000.0p-35,
+ 0xd10000.0p-23, 0xb40000.0p-33,
+ 0xd20000.0p-23, -0x800000.0p-35,
+ 0xd30000.0p-23, 0xaa0000.0p-33,
+ 0xd40000.0p-23, -0xe00000.0p-35,
+ 0xd50000.0p-23, 0x880000.0p-33,
+ 0xd60000.0p-23, -0xd00000.0p-34,
+ 0xd70000.0p-23, 0x9c0000.0p-34,
+ 0xd80000.0p-23, -0xb00000.0p-33,
+ 0xd90000.0p-23, -0x800000.0p-38,
+ 0xda0000.0p-23, 0xa40000.0p-33,
+ 0xdb0000.0p-23, -0xdc0000.0p-34,
+ 0xdc0000.0p-23, 0xc00000.0p-35,
+ 0xdd0000.0p-23, 0xca0000.0p-33,
+ 0xde0000.0p-23, -0xb80000.0p-34,
+ 0xdf0000.0p-23, 0xd00000.0p-35,
+ 0xe00000.0p-23, 0xc00000.0p-33,
+ 0xe10000.0p-23, -0xf40000.0p-34,
+ 0xe20000.0p-23, 0x800000.0p-37,
+ 0xe30000.0p-23, 0x860000.0p-33,
+ 0xe40000.0p-23, -0xc80000.0p-33,
+ 0xe50000.0p-23, -0xa80000.0p-34,
+ 0xe60000.0p-23, 0xe00000.0p-36,
+ 0xe70000.0p-23, 0x880000.0p-33,
+ 0xe80000.0p-23, -0xe00000.0p-33,
+ 0xe90000.0p-23, -0xfc0000.0p-34,
+ 0xea0000.0p-23, -0x800000.0p-35,
+ 0xeb0000.0p-23, 0xe80000.0p-35,
+ 0xec0000.0p-23, 0x900000.0p-33,
+ 0xed0000.0p-23, 0xe20000.0p-33,
+ 0xee0000.0p-23, -0xac0000.0p-33,
+ 0xef0000.0p-23, -0xc80000.0p-34,
+ 0xf00000.0p-23, -0x800000.0p-35,
+ 0xf10000.0p-23, 0x800000.0p-35,
+ 0xf20000.0p-23, 0xb80000.0p-34,
+ 0xf30000.0p-23, 0x940000.0p-33,
+ 0xf40000.0p-23, 0xc80000.0p-33,
+ 0xf50000.0p-23, -0xf20000.0p-33,
+ 0xf60000.0p-23, -0xc80000.0p-33,
+ 0xf70000.0p-23, -0xa20000.0p-33,
+ 0xf80000.0p-23, -0x800000.0p-33,
+ 0xf90000.0p-23, -0xc40000.0p-34,
+ 0xfa0000.0p-23, -0x900000.0p-34,
+ 0xfb0000.0p-23, -0xc80000.0p-35,
+ 0xfc0000.0p-23, -0x800000.0p-35,
+ 0xfd0000.0p-23, -0x900000.0p-36,
+ 0xfe0000.0p-23, -0x800000.0p-37,
+ 0xff0000.0p-23, -0x800000.0p-39,
+ 0x800000.0p-22, 0,
+};
+#endif /* USE_UTAB */
+
+#ifdef STRUCT_RETURN
+#define RETURN1(rp, v) do { \
+ (rp)->hi = (v); \
+ (rp)->lo_set = 0; \
+ return; \
+} while (0)
+
+#define RETURN2(rp, h, l) do { \
+ (rp)->hi = (h); \
+ (rp)->lo = (l); \
+ (rp)->lo_set = 1; \
+ return; \
+} while (0)
+
+struct ld {
+ long double hi;
+ long double lo;
+ int lo_set;
+};
+#else
+#define RETURN1(rp, v) RETURNF(v)
+#define RETURN2(rp, h, l) RETURNI((h) + (l))
+#endif
+
+#ifdef STRUCT_RETURN
+static inline __always_inline void
+k_logl(long double x, struct ld *rp)
+#else
+long double
+logl(long double x)
+#endif
+{
+ long double d, dk, val_hi, val_lo, z;
+ uint64_t ix, lx;
+ int i, k;
+ uint16_t hx;
+
+ EXTRACT_LDBL80_WORDS(hx, lx, x);
+ k = -16383;
+#if 0 /* Hard to do efficiently. Don't do it until we support all modes. */
+ if (x == 1)
+ RETURN1(rp, 0); /* log(1) = +0 in all rounding modes */
+#endif
+ if (hx == 0 || hx >= 0x8000) { /* zero, negative or subnormal? */
+ if (((hx & 0x7fff) | lx) == 0)
+ RETURN1(rp, -1 / zero); /* log(+-0) = -Inf */
+ if (hx != 0)
+ /* log(neg or [pseudo-]NaN) = qNaN: */
+ RETURN1(rp, (x - x) / zero);
+ x *= 0x1.0p65; /* subnormal; scale up x */
+ /* including pseudo-subnormals */
+ EXTRACT_LDBL80_WORDS(hx, lx, x);
+ k = -16383 - 65;
+ } else if (hx >= 0x7fff || (lx & 0x8000000000000000ULL) == 0)
+ RETURN1(rp, x + x); /* log(Inf or NaN) = Inf or qNaN */
+ /* log(pseudo-Inf) = qNaN */
+ /* log(pseudo-NaN) = qNaN */
+ /* log(unnormal) = qNaN */
+#ifndef STRUCT_RETURN
+ ENTERI();
+#endif
+ k += hx;
+ ix = lx & 0x7fffffffffffffffULL;
+ dk = k;
+
+ /* Scale x to be in [1, 2). */
+ SET_LDBL_EXPSIGN(x, 0x3fff);
+
+ /* 0 <= i <= INTERVALS: */
+#define L2I (64 - LOG2_INTERVALS)
+ i = (ix + (1LL << (L2I - 2))) >> (L2I - 1);
+
+ /*
+ * -0.005280 < d < 0.004838. In particular, the infinite-
+ * precision |d| is <= 2**-7. Rounding of G(i) to 8 bits
+ * ensures that d is representable without extra precision for
+ * this bound on |d| (since when this calculation is expressed
+ * as x*G(i)-1, the multiplication needs as many extra bits as
+ * G(i) has and the subtraction cancels 8 bits). But for
+ * most i (107 cases out of 129), the infinite-precision |d|
+ * is <= 2**-8. G(i) is rounded to 9 bits for such i to give
+ * better accuracy (this works by improving the bound on |d|,
+ * which in turn allows rounding to 9 bits in more cases).
+ * This is only important when the original x is near 1 -- it
+ * lets us avoid using a special method to give the desired
+ * accuracy for such x.
+ */
+ if (0)
+ d = x * G(i) - 1;
+ else {
+#ifdef USE_UTAB
+ d = (x - H(i)) * G(i) + E(i);
+#else
+ long double x_hi, x_lo;
+ float fx_hi;
+
+ /*
+ * Split x into x_hi + x_lo to calculate x*G(i)-1 exactly.
+ * G(i) has at most 9 bits, so the splitting point is not
+ * critical.
+ */
+ SET_FLOAT_WORD(fx_hi, (lx >> 40) | 0x3f800000);
+ x_hi = fx_hi;
+ x_lo = x - x_hi;
+ d = x_hi * G(i) - 1 + x_lo * G(i);
+#endif
+ }
+
+ /*
+ * Our algorithm depends on exact cancellation of F_lo(i) and
+ * F_hi(i) with dk*ln_2_lo and dk*ln2_hi when k is -1 and i is
+ * at the end of the table. This and other technical complications
+ * make it difficult to avoid the double scaling in (dk*ln2) *
+ * log(base) for base != e without losing more accuracy and/or
+ * efficiency than is gained.
+ */
+ z = d * d;
+ val_lo = z * d * z * (z * (d * P8 + P7) + (d * P6 + P5)) +
+ (F_lo(i) + dk * ln2_lo + z * d * (d * P4 + P3)) + z * P2;
+ val_hi = d;
+#ifdef DEBUG
+ if (fetestexcept(FE_UNDERFLOW))
+ breakpoint();
+#endif
+
+ _3sumF(val_hi, val_lo, F_hi(i) + dk * ln2_hi);
+ RETURN2(rp, val_hi, val_lo);
+}
+
+long double
+log1pl(long double x)
+{
+ long double d, d_hi, d_lo, dk, f_lo, val_hi, val_lo, z;
+ long double f_hi, twopminusk;
+ uint64_t ix, lx;
+ int i, k;
+ int16_t ax, hx;
+
+ DOPRINT_START(&x);
+ EXTRACT_LDBL80_WORDS(hx, lx, x);
+ if (hx < 0x3fff) { /* x < 1, or x neg NaN */
+ ax = hx & 0x7fff;
+ if (ax >= 0x3fff) { /* x <= -1, or x neg NaN */
+ if (ax == 0x3fff && lx == 0x8000000000000000ULL)
+ RETURNP(-1 / zero); /* log1p(-1) = -Inf */
+ /* log1p(x < 1, or x [pseudo-]NaN) = qNaN: */
+ RETURNP((x - x) / (x - x));
+ }
+ if (ax <= 0x3fbe) { /* |x| < 2**-64 */
+ if ((int)x == 0)
+ RETURNP(x); /* x with inexact if x != 0 */
+ }
+ f_hi = 1;
+ f_lo = x;
+ } else if (hx >= 0x7fff) { /* x +Inf or non-neg NaN */
+ RETURNP(x + x); /* log1p(Inf or NaN) = Inf or qNaN */
+ /* log1p(pseudo-Inf) = qNaN */
+ /* log1p(pseudo-NaN) = qNaN */
+ /* log1p(unnormal) = qNaN */
+ } else if (hx < 0x407f) { /* 1 <= x < 2**128 */
+ f_hi = x;
+ f_lo = 1;
+ } else { /* 2**128 <= x < +Inf */
+ f_hi = x;
+ f_lo = 0; /* avoid underflow of the P5 term */
+ }
+ ENTERI();
+ x = f_hi + f_lo;
+ f_lo = (f_hi - x) + f_lo;
+
+ EXTRACT_LDBL80_WORDS(hx, lx, x);
+ k = -16383;
+
+ k += hx;
+ ix = lx & 0x7fffffffffffffffULL;
+ dk = k;
+
+ SET_LDBL_EXPSIGN(x, 0x3fff);
+ twopminusk = 1;
+ SET_LDBL_EXPSIGN(twopminusk, 0x7ffe - (hx & 0x7fff));
+ f_lo *= twopminusk;
+
+ i = (ix + (1LL << (L2I - 2))) >> (L2I - 1);
+
+ /*
+ * x*G(i)-1 (with a reduced x) can be represented exactly, as
+ * above, but now we need to evaluate the polynomial on d =
+ * (x+f_lo)*G(i)-1 and extra precision is needed for that.
+ * Since x+x_lo is a hi+lo decomposition and subtracting 1
+ * doesn't lose too many bits, an inexact calculation for
+ * f_lo*G(i) is good enough.
+ */
+ if (0)
+ d_hi = x * G(i) - 1;
+ else {
+#ifdef USE_UTAB
+ d_hi = (x - H(i)) * G(i) + E(i);
+#else
+ long double x_hi, x_lo;
+ float fx_hi;
+
+ SET_FLOAT_WORD(fx_hi, (lx >> 40) | 0x3f800000);
+ x_hi = fx_hi;
+ x_lo = x - x_hi;
+ d_hi = x_hi * G(i) - 1 + x_lo * G(i);
+#endif
+ }
+ d_lo = f_lo * G(i);
+
+ /*
+ * This is _2sumF(d_hi, d_lo) inlined. The condition
+ * (d_hi == 0 || |d_hi| >= |d_lo|) for using _2sumF() is not
+ * always satisifed, so it is not clear that this works, but
+ * it works in practice. It works even if it gives a wrong
+ * normalized d_lo, since |d_lo| > |d_hi| implies that i is
+ * nonzero and d is tiny, so the F(i) term dominates d_lo.
+ * In float precision:
+ * (By exhaustive testing, the worst case is d_hi = 0x1.bp-25.
+ * And if d is only a little tinier than that, we would have
+ * another underflow problem for the P3 term; this is also ruled
+ * out by exhaustive testing.)
+ */
+ d = d_hi + d_lo;
+ d_lo = d_hi - d + d_lo;
+ d_hi = d;
+
+ z = d * d;
+ val_lo = z * d * z * (z * (d * P8 + P7) + (d * P6 + P5)) +
+ (F_lo(i) + dk * ln2_lo + d_lo + z * d * (d * P4 + P3)) + z * P2;
+ val_hi = d_hi;
+#ifdef DEBUG
+ if (fetestexcept(FE_UNDERFLOW))
+ breakpoint();
+#endif
+
+ _3sumF(val_hi, val_lo, F_hi(i) + dk * ln2_hi);
+ RETURN2PI(val_hi, val_lo);
+}
+
+#ifdef STRUCT_RETURN
+
+long double
+logl(long double x)
+{
+ struct ld r;
+
+ ENTERI();
+ DOPRINT_START(&x);
+ k_logl(x, &r);
+ RETURNSPI(&r);
+}
+
+static const double
+invln10_hi = 4.3429448190317999e-1, /* 0x1bcb7b1526e000.0p-54 */
+invln10_lo = 7.1842412889749798e-14, /* 0x1438ca9aadd558.0p-96 */
+invln2_hi = 1.4426950408887933e0, /* 0x171547652b8000.0p-52 */
+invln2_lo = 1.7010652264631490e-13; /* 0x17f0bbbe87fed0.0p-95 */
+
+long double
+log10l(long double x)
+{
+ struct ld r;
+ long double hi, lo;
+
+ ENTERI();
+ DOPRINT_START(&x);
+ k_logl(x, &r);
+ if (!r.lo_set)
+ RETURNPI(r.hi);
+ _2sumF(r.hi, r.lo);
+ hi = (float)r.hi;
+ lo = r.lo + (r.hi - hi);
+ RETURN2PI(invln10_hi * hi,
+ (invln10_lo + invln10_hi) * lo + invln10_lo * hi);
+}
+
+long double
+log2l(long double x)
+{
+ struct ld r;
+ long double hi, lo;
+
+ ENTERI();
+ DOPRINT_START(&x);
+ k_logl(x, &r);
+ if (!r.lo_set)
+ RETURNPI(r.hi);
+ _2sumF(r.hi, r.lo);
+ hi = (float)r.hi;
+ lo = r.lo + (r.hi - hi);
+ RETURN2PI(invln2_hi * hi,
+ (invln2_lo + invln2_hi) * lo + invln2_lo * hi);
+}
+
+#endif /* STRUCT_RETURN */
Property changes on: trunk/lib/msun/ld80/s_logl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/lib/msun/ld80/s_nanl.c
===================================================================
--- trunk/lib/msun/ld80/s_nanl.c 2018-06-09 15:11:35 UTC (rev 10595)
+++ trunk/lib/msun/ld80/s_nanl.c 2018-06-09 15:11:51 UTC (rev 10596)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2007 David Schultz
* All rights reserved.
@@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/msun/ld80/s_nanl.c 174759 2007-12-18 23:46:32Z das $
*/
#include <math.h>
More information about the Midnightbsd-cvs
mailing list