xref: /minix3/lib/libm/noieee_src/n_log.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*      $NetBSD: n_log.c,v 1.8 2014/10/10 20:58:09 martin Exp $ */
22fe8fb19SBen Gras /*
32fe8fb19SBen Gras  * Copyright (c) 1992, 1993
42fe8fb19SBen Gras  *	The Regents of the University of California.  All rights reserved.
52fe8fb19SBen Gras  *
62fe8fb19SBen Gras  * Redistribution and use in source and binary forms, with or without
72fe8fb19SBen Gras  * modification, are permitted provided that the following conditions
82fe8fb19SBen Gras  * are met:
92fe8fb19SBen Gras  * 1. Redistributions of source code must retain the above copyright
102fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer.
112fe8fb19SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
122fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer in the
132fe8fb19SBen Gras  *    documentation and/or other materials provided with the distribution.
142fe8fb19SBen Gras  * 3. Neither the name of the University nor the names of its contributors
152fe8fb19SBen Gras  *    may be used to endorse or promote products derived from this software
162fe8fb19SBen Gras  *    without specific prior written permission.
172fe8fb19SBen Gras  *
182fe8fb19SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
192fe8fb19SBen Gras  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
202fe8fb19SBen Gras  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
212fe8fb19SBen Gras  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
222fe8fb19SBen Gras  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
232fe8fb19SBen Gras  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
242fe8fb19SBen Gras  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
252fe8fb19SBen Gras  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
262fe8fb19SBen Gras  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
272fe8fb19SBen Gras  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
282fe8fb19SBen Gras  * SUCH DAMAGE.
292fe8fb19SBen Gras  */
302fe8fb19SBen Gras 
312fe8fb19SBen Gras #ifndef lint
322fe8fb19SBen Gras #if 0
332fe8fb19SBen Gras static char sccsid[] = "@(#)log.c	8.2 (Berkeley) 11/30/93";
342fe8fb19SBen Gras #endif
352fe8fb19SBen Gras #endif /* not lint */
362fe8fb19SBen Gras 
372fe8fb19SBen Gras #include "../src/namespace.h"
382fe8fb19SBen Gras 
392fe8fb19SBen Gras #include <math.h>
402fe8fb19SBen Gras #include <errno.h>
412fe8fb19SBen Gras 
422fe8fb19SBen Gras #include "mathimpl.h"
432fe8fb19SBen Gras 
442fe8fb19SBen Gras #ifdef __weak_alias
452fe8fb19SBen Gras __weak_alias(log, _log);
46*0a6a1f1dSLionel Sambuc __weak_alias(_logl, _log);
472fe8fb19SBen Gras __weak_alias(logf, _logf);
482fe8fb19SBen Gras #endif
492fe8fb19SBen Gras 
502fe8fb19SBen Gras /* Table-driven natural logarithm.
512fe8fb19SBen Gras  *
522fe8fb19SBen Gras  * This code was derived, with minor modifications, from:
532fe8fb19SBen Gras  *	Peter Tang, "Table-Driven Implementation of the
542fe8fb19SBen Gras  *	Logarithm in IEEE Floating-Point arithmetic." ACM Trans.
552fe8fb19SBen Gras  *	Math Software, vol 16. no 4, pp 378-400, Dec 1990).
562fe8fb19SBen Gras  *
572fe8fb19SBen Gras  * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256,
582fe8fb19SBen Gras  * where F = j/128 for j an integer in [0, 128].
592fe8fb19SBen Gras  *
602fe8fb19SBen Gras  * log(2^m) = log2_hi*m + log2_tail*m
612fe8fb19SBen Gras  * since m is an integer, the dominant term is exact.
622fe8fb19SBen Gras  * m has at most 10 digits (for subnormal numbers),
632fe8fb19SBen Gras  * and log2_hi has 11 trailing zero bits.
642fe8fb19SBen Gras  *
652fe8fb19SBen Gras  * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h
662fe8fb19SBen Gras  * logF_hi[] + 512 is exact.
672fe8fb19SBen Gras  *
682fe8fb19SBen Gras  * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ...
692fe8fb19SBen Gras  * the leading term is calculated to extra precision in two
702fe8fb19SBen Gras  * parts, the larger of which adds exactly to the dominant
712fe8fb19SBen Gras  * m and F terms.
722fe8fb19SBen Gras  * There are two cases:
732fe8fb19SBen Gras  *	1. when m, j are non-zero (m | j), use absolute
742fe8fb19SBen Gras  *	   precision for the leading term.
752fe8fb19SBen Gras  *	2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
762fe8fb19SBen Gras  *	   In this case, use a relative precision of 24 bits.
772fe8fb19SBen Gras  * (This is done differently in the original paper)
782fe8fb19SBen Gras  *
792fe8fb19SBen Gras  * Special cases:
802fe8fb19SBen Gras  *	0	return signalling -Inf
812fe8fb19SBen Gras  *	neg	return signalling NaN
822fe8fb19SBen Gras  *	+Inf	return +Inf
832fe8fb19SBen Gras */
842fe8fb19SBen Gras 
852fe8fb19SBen Gras #if defined(__vax__) || defined(tahoe)
862fe8fb19SBen Gras #define _IEEE		0
872fe8fb19SBen Gras #define TRUNC(x)	x = (double) (float) (x)
882fe8fb19SBen Gras #else
892fe8fb19SBen Gras #define _IEEE		1
902fe8fb19SBen Gras #define endian		(((*(int *) &one)) ? 1 : 0)
912fe8fb19SBen Gras #define TRUNC(x)	*(((int *) &x) + endian) &= 0xf8000000
922fe8fb19SBen Gras #define infnan(x)	0.0
932fe8fb19SBen Gras #endif
942fe8fb19SBen Gras 
952fe8fb19SBen Gras #define N 128
962fe8fb19SBen Gras 
972fe8fb19SBen Gras /* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
982fe8fb19SBen Gras  * Used for generation of extend precision logarithms.
992fe8fb19SBen Gras  * The constant 35184372088832 is 2^45, so the divide is exact.
1002fe8fb19SBen Gras  * It ensures correct reading of logF_head, even for inaccurate
1012fe8fb19SBen Gras  * decimal-to-binary conversion routines.  (Everybody gets the
1022fe8fb19SBen Gras  * right answer for integers less than 2^53.)
1032fe8fb19SBen Gras  * Values for log(F) were generated using error < 10^-57 absolute
1042fe8fb19SBen Gras  * with the bc -l package.
1052fe8fb19SBen Gras */
1062fe8fb19SBen Gras static const double	A1 = 	  .08333333333333178827;
1072fe8fb19SBen Gras static const double	A2 = 	  .01250000000377174923;
1082fe8fb19SBen Gras static const double	A3 =	 .002232139987919447809;
1092fe8fb19SBen Gras static const double	A4 =	.0004348877777076145742;
1102fe8fb19SBen Gras 
1112fe8fb19SBen Gras static const double logF_head[N+1] = {
1122fe8fb19SBen Gras 	0.,
1132fe8fb19SBen Gras 	.007782140442060381246,
1142fe8fb19SBen Gras 	.015504186535963526694,
1152fe8fb19SBen Gras 	.023167059281547608406,
1162fe8fb19SBen Gras 	.030771658666765233647,
1172fe8fb19SBen Gras 	.038318864302141264488,
1182fe8fb19SBen Gras 	.045809536031242714670,
1192fe8fb19SBen Gras 	.053244514518837604555,
1202fe8fb19SBen Gras 	.060624621816486978786,
1212fe8fb19SBen Gras 	.067950661908525944454,
1222fe8fb19SBen Gras 	.075223421237524235039,
1232fe8fb19SBen Gras 	.082443669210988446138,
1242fe8fb19SBen Gras 	.089612158689760690322,
1252fe8fb19SBen Gras 	.096729626458454731618,
1262fe8fb19SBen Gras 	.103796793681567578460,
1272fe8fb19SBen Gras 	.110814366340264314203,
1282fe8fb19SBen Gras 	.117783035656430001836,
1292fe8fb19SBen Gras 	.124703478501032805070,
1302fe8fb19SBen Gras 	.131576357788617315236,
1312fe8fb19SBen Gras 	.138402322859292326029,
1322fe8fb19SBen Gras 	.145182009844575077295,
1332fe8fb19SBen Gras 	.151916042025732167530,
1342fe8fb19SBen Gras 	.158605030176659056451,
1352fe8fb19SBen Gras 	.165249572895390883786,
1362fe8fb19SBen Gras 	.171850256926518341060,
1372fe8fb19SBen Gras 	.178407657472689606947,
1382fe8fb19SBen Gras 	.184922338493834104156,
1392fe8fb19SBen Gras 	.191394852999565046047,
1402fe8fb19SBen Gras 	.197825743329758552135,
1412fe8fb19SBen Gras 	.204215541428766300668,
1422fe8fb19SBen Gras 	.210564769107350002741,
1432fe8fb19SBen Gras 	.216873938300523150246,
1442fe8fb19SBen Gras 	.223143551314024080056,
1452fe8fb19SBen Gras 	.229374101064877322642,
1462fe8fb19SBen Gras 	.235566071312860003672,
1472fe8fb19SBen Gras 	.241719936886966024758,
1482fe8fb19SBen Gras 	.247836163904594286577,
1492fe8fb19SBen Gras 	.253915209980732470285,
1502fe8fb19SBen Gras 	.259957524436686071567,
1512fe8fb19SBen Gras 	.265963548496984003577,
1522fe8fb19SBen Gras 	.271933715484010463114,
1532fe8fb19SBen Gras 	.277868451003087102435,
1542fe8fb19SBen Gras 	.283768173130738432519,
1552fe8fb19SBen Gras 	.289633292582948342896,
1562fe8fb19SBen Gras 	.295464212893421063199,
1572fe8fb19SBen Gras 	.301261330578199704177,
1582fe8fb19SBen Gras 	.307025035294827830512,
1592fe8fb19SBen Gras 	.312755710004239517729,
1602fe8fb19SBen Gras 	.318453731118097493890,
1612fe8fb19SBen Gras 	.324119468654316733591,
1622fe8fb19SBen Gras 	.329753286372579168528,
1632fe8fb19SBen Gras 	.335355541920762334484,
1642fe8fb19SBen Gras 	.340926586970454081892,
1652fe8fb19SBen Gras 	.346466767346100823488,
1662fe8fb19SBen Gras 	.351976423156884266063,
1672fe8fb19SBen Gras 	.357455888922231679316,
1682fe8fb19SBen Gras 	.362905493689140712376,
1692fe8fb19SBen Gras 	.368325561158599157352,
1702fe8fb19SBen Gras 	.373716409793814818840,
1712fe8fb19SBen Gras 	.379078352934811846353,
1722fe8fb19SBen Gras 	.384411698910298582632,
1732fe8fb19SBen Gras 	.389716751140440464951,
1742fe8fb19SBen Gras 	.394993808240542421117,
1752fe8fb19SBen Gras 	.400243164127459749579,
1762fe8fb19SBen Gras 	.405465108107819105498,
1772fe8fb19SBen Gras 	.410659924985338875558,
1782fe8fb19SBen Gras 	.415827895143593195825,
1792fe8fb19SBen Gras 	.420969294644237379543,
1802fe8fb19SBen Gras 	.426084395310681429691,
1812fe8fb19SBen Gras 	.431173464818130014464,
1822fe8fb19SBen Gras 	.436236766774527495726,
1832fe8fb19SBen Gras 	.441274560805140936281,
1842fe8fb19SBen Gras 	.446287102628048160113,
1852fe8fb19SBen Gras 	.451274644139630254358,
1862fe8fb19SBen Gras 	.456237433481874177232,
1872fe8fb19SBen Gras 	.461175715122408291790,
1882fe8fb19SBen Gras 	.466089729924533457960,
1892fe8fb19SBen Gras 	.470979715219073113985,
1902fe8fb19SBen Gras 	.475845904869856894947,
1912fe8fb19SBen Gras 	.480688529345570714212,
1922fe8fb19SBen Gras 	.485507815781602403149,
1932fe8fb19SBen Gras 	.490303988045525329653,
1942fe8fb19SBen Gras 	.495077266798034543171,
1952fe8fb19SBen Gras 	.499827869556611403822,
1962fe8fb19SBen Gras 	.504556010751912253908,
1972fe8fb19SBen Gras 	.509261901790523552335,
1982fe8fb19SBen Gras 	.513945751101346104405,
1992fe8fb19SBen Gras 	.518607764208354637958,
2002fe8fb19SBen Gras 	.523248143765158602036,
2012fe8fb19SBen Gras 	.527867089620485785417,
2022fe8fb19SBen Gras 	.532464798869114019908,
2032fe8fb19SBen Gras 	.537041465897345915436,
2042fe8fb19SBen Gras 	.541597282432121573947,
2052fe8fb19SBen Gras 	.546132437597407260909,
2062fe8fb19SBen Gras 	.550647117952394182793,
2072fe8fb19SBen Gras 	.555141507540611200965,
2082fe8fb19SBen Gras 	.559615787935399566777,
2092fe8fb19SBen Gras 	.564070138285387656651,
2102fe8fb19SBen Gras 	.568504735352689749561,
2112fe8fb19SBen Gras 	.572919753562018740922,
2122fe8fb19SBen Gras 	.577315365035246941260,
2132fe8fb19SBen Gras 	.581691739635061821900,
2142fe8fb19SBen Gras 	.586049045003164792433,
2152fe8fb19SBen Gras 	.590387446602107957005,
2162fe8fb19SBen Gras 	.594707107746216934174,
2172fe8fb19SBen Gras 	.599008189645246602594,
2182fe8fb19SBen Gras 	.603290851438941899687,
2192fe8fb19SBen Gras 	.607555250224322662688,
2202fe8fb19SBen Gras 	.611801541106615331955,
2212fe8fb19SBen Gras 	.616029877215623855590,
2222fe8fb19SBen Gras 	.620240409751204424537,
2232fe8fb19SBen Gras 	.624433288012369303032,
2242fe8fb19SBen Gras 	.628608659422752680256,
2252fe8fb19SBen Gras 	.632766669570628437213,
2262fe8fb19SBen Gras 	.636907462236194987781,
2272fe8fb19SBen Gras 	.641031179420679109171,
2282fe8fb19SBen Gras 	.645137961373620782978,
2292fe8fb19SBen Gras 	.649227946625615004450,
2302fe8fb19SBen Gras 	.653301272011958644725,
2312fe8fb19SBen Gras 	.657358072709030238911,
2322fe8fb19SBen Gras 	.661398482245203922502,
2332fe8fb19SBen Gras 	.665422632544505177065,
2342fe8fb19SBen Gras 	.669430653942981734871,
2352fe8fb19SBen Gras 	.673422675212350441142,
2362fe8fb19SBen Gras 	.677398823590920073911,
2372fe8fb19SBen Gras 	.681359224807238206267,
2382fe8fb19SBen Gras 	.685304003098281100392,
2392fe8fb19SBen Gras 	.689233281238557538017,
2402fe8fb19SBen Gras 	.693147180560117703862
2412fe8fb19SBen Gras };
2422fe8fb19SBen Gras 
2432fe8fb19SBen Gras static const double logF_tail[N+1] = {
2442fe8fb19SBen Gras 	0.,
2452fe8fb19SBen Gras 	-.00000000000000543229938420049,
2462fe8fb19SBen Gras 	 .00000000000000172745674997061,
2472fe8fb19SBen Gras 	-.00000000000001323017818229233,
2482fe8fb19SBen Gras 	-.00000000000001154527628289872,
2492fe8fb19SBen Gras 	-.00000000000000466529469958300,
2502fe8fb19SBen Gras 	 .00000000000005148849572685810,
2512fe8fb19SBen Gras 	-.00000000000002532168943117445,
2522fe8fb19SBen Gras 	-.00000000000005213620639136504,
2532fe8fb19SBen Gras 	-.00000000000001819506003016881,
2542fe8fb19SBen Gras 	 .00000000000006329065958724544,
2552fe8fb19SBen Gras 	 .00000000000008614512936087814,
2562fe8fb19SBen Gras 	-.00000000000007355770219435028,
2572fe8fb19SBen Gras 	 .00000000000009638067658552277,
2582fe8fb19SBen Gras 	 .00000000000007598636597194141,
2592fe8fb19SBen Gras 	 .00000000000002579999128306990,
2602fe8fb19SBen Gras 	-.00000000000004654729747598444,
2612fe8fb19SBen Gras 	-.00000000000007556920687451336,
2622fe8fb19SBen Gras 	 .00000000000010195735223708472,
2632fe8fb19SBen Gras 	-.00000000000017319034406422306,
2642fe8fb19SBen Gras 	-.00000000000007718001336828098,
2652fe8fb19SBen Gras 	 .00000000000010980754099855238,
2662fe8fb19SBen Gras 	-.00000000000002047235780046195,
2672fe8fb19SBen Gras 	-.00000000000008372091099235912,
2682fe8fb19SBen Gras 	 .00000000000014088127937111135,
2692fe8fb19SBen Gras 	 .00000000000012869017157588257,
2702fe8fb19SBen Gras 	 .00000000000017788850778198106,
2712fe8fb19SBen Gras 	 .00000000000006440856150696891,
2722fe8fb19SBen Gras 	 .00000000000016132822667240822,
2732fe8fb19SBen Gras 	-.00000000000007540916511956188,
2742fe8fb19SBen Gras 	-.00000000000000036507188831790,
2752fe8fb19SBen Gras 	 .00000000000009120937249914984,
2762fe8fb19SBen Gras 	 .00000000000018567570959796010,
2772fe8fb19SBen Gras 	-.00000000000003149265065191483,
2782fe8fb19SBen Gras 	-.00000000000009309459495196889,
2792fe8fb19SBen Gras 	 .00000000000017914338601329117,
2802fe8fb19SBen Gras 	-.00000000000001302979717330866,
2812fe8fb19SBen Gras 	 .00000000000023097385217586939,
2822fe8fb19SBen Gras 	 .00000000000023999540484211737,
2832fe8fb19SBen Gras 	 .00000000000015393776174455408,
2842fe8fb19SBen Gras 	-.00000000000036870428315837678,
2852fe8fb19SBen Gras 	 .00000000000036920375082080089,
2862fe8fb19SBen Gras 	-.00000000000009383417223663699,
2872fe8fb19SBen Gras 	 .00000000000009433398189512690,
2882fe8fb19SBen Gras 	 .00000000000041481318704258568,
2892fe8fb19SBen Gras 	-.00000000000003792316480209314,
2902fe8fb19SBen Gras 	 .00000000000008403156304792424,
2912fe8fb19SBen Gras 	-.00000000000034262934348285429,
2922fe8fb19SBen Gras 	 .00000000000043712191957429145,
2932fe8fb19SBen Gras 	-.00000000000010475750058776541,
2942fe8fb19SBen Gras 	-.00000000000011118671389559323,
2952fe8fb19SBen Gras 	 .00000000000037549577257259853,
2962fe8fb19SBen Gras 	 .00000000000013912841212197565,
2972fe8fb19SBen Gras 	 .00000000000010775743037572640,
2982fe8fb19SBen Gras 	 .00000000000029391859187648000,
2992fe8fb19SBen Gras 	-.00000000000042790509060060774,
3002fe8fb19SBen Gras 	 .00000000000022774076114039555,
3012fe8fb19SBen Gras 	 .00000000000010849569622967912,
3022fe8fb19SBen Gras 	-.00000000000023073801945705758,
3032fe8fb19SBen Gras 	 .00000000000015761203773969435,
3042fe8fb19SBen Gras 	 .00000000000003345710269544082,
3052fe8fb19SBen Gras 	-.00000000000041525158063436123,
3062fe8fb19SBen Gras 	 .00000000000032655698896907146,
3072fe8fb19SBen Gras 	-.00000000000044704265010452446,
3082fe8fb19SBen Gras 	 .00000000000034527647952039772,
3092fe8fb19SBen Gras 	-.00000000000007048962392109746,
3102fe8fb19SBen Gras 	 .00000000000011776978751369214,
3112fe8fb19SBen Gras 	-.00000000000010774341461609578,
3122fe8fb19SBen Gras 	 .00000000000021863343293215910,
3132fe8fb19SBen Gras 	 .00000000000024132639491333131,
3142fe8fb19SBen Gras 	 .00000000000039057462209830700,
3152fe8fb19SBen Gras 	-.00000000000026570679203560751,
3162fe8fb19SBen Gras 	 .00000000000037135141919592021,
3172fe8fb19SBen Gras 	-.00000000000017166921336082431,
3182fe8fb19SBen Gras 	-.00000000000028658285157914353,
3192fe8fb19SBen Gras 	-.00000000000023812542263446809,
3202fe8fb19SBen Gras 	 .00000000000006576659768580062,
3212fe8fb19SBen Gras 	-.00000000000028210143846181267,
3222fe8fb19SBen Gras 	 .00000000000010701931762114254,
3232fe8fb19SBen Gras 	 .00000000000018119346366441110,
3242fe8fb19SBen Gras 	 .00000000000009840465278232627,
3252fe8fb19SBen Gras 	-.00000000000033149150282752542,
3262fe8fb19SBen Gras 	-.00000000000018302857356041668,
3272fe8fb19SBen Gras 	-.00000000000016207400156744949,
3282fe8fb19SBen Gras 	 .00000000000048303314949553201,
3292fe8fb19SBen Gras 	-.00000000000071560553172382115,
3302fe8fb19SBen Gras 	 .00000000000088821239518571855,
3312fe8fb19SBen Gras 	-.00000000000030900580513238244,
3322fe8fb19SBen Gras 	-.00000000000061076551972851496,
3332fe8fb19SBen Gras 	 .00000000000035659969663347830,
3342fe8fb19SBen Gras 	 .00000000000035782396591276383,
3352fe8fb19SBen Gras 	-.00000000000046226087001544578,
3362fe8fb19SBen Gras 	 .00000000000062279762917225156,
3372fe8fb19SBen Gras 	 .00000000000072838947272065741,
3382fe8fb19SBen Gras 	 .00000000000026809646615211673,
3392fe8fb19SBen Gras 	-.00000000000010960825046059278,
3402fe8fb19SBen Gras 	 .00000000000002311949383800537,
3412fe8fb19SBen Gras 	-.00000000000058469058005299247,
3422fe8fb19SBen Gras 	-.00000000000002103748251144494,
3432fe8fb19SBen Gras 	-.00000000000023323182945587408,
3442fe8fb19SBen Gras 	-.00000000000042333694288141916,
3452fe8fb19SBen Gras 	-.00000000000043933937969737844,
3462fe8fb19SBen Gras 	 .00000000000041341647073835565,
3472fe8fb19SBen Gras 	 .00000000000006841763641591466,
3482fe8fb19SBen Gras 	 .00000000000047585534004430641,
3492fe8fb19SBen Gras 	 .00000000000083679678674757695,
3502fe8fb19SBen Gras 	-.00000000000085763734646658640,
3512fe8fb19SBen Gras 	 .00000000000021913281229340092,
3522fe8fb19SBen Gras 	-.00000000000062242842536431148,
3532fe8fb19SBen Gras 	-.00000000000010983594325438430,
3542fe8fb19SBen Gras 	 .00000000000065310431377633651,
3552fe8fb19SBen Gras 	-.00000000000047580199021710769,
3562fe8fb19SBen Gras 	-.00000000000037854251265457040,
3572fe8fb19SBen Gras 	 .00000000000040939233218678664,
3582fe8fb19SBen Gras 	 .00000000000087424383914858291,
3592fe8fb19SBen Gras 	 .00000000000025218188456842882,
3602fe8fb19SBen Gras 	-.00000000000003608131360422557,
3612fe8fb19SBen Gras 	-.00000000000050518555924280902,
3622fe8fb19SBen Gras 	 .00000000000078699403323355317,
3632fe8fb19SBen Gras 	-.00000000000067020876961949060,
3642fe8fb19SBen Gras 	 .00000000000016108575753932458,
3652fe8fb19SBen Gras 	 .00000000000058527188436251509,
3662fe8fb19SBen Gras 	-.00000000000035246757297904791,
3672fe8fb19SBen Gras 	-.00000000000018372084495629058,
3682fe8fb19SBen Gras 	 .00000000000088606689813494916,
3692fe8fb19SBen Gras 	 .00000000000066486268071468700,
3702fe8fb19SBen Gras 	 .00000000000063831615170646519,
3712fe8fb19SBen Gras 	 .00000000000025144230728376072,
3722fe8fb19SBen Gras 	-.00000000000017239444525614834
3732fe8fb19SBen Gras };
3742fe8fb19SBen Gras 
3752fe8fb19SBen Gras double
log(double x)3762fe8fb19SBen Gras log(double x)
3772fe8fb19SBen Gras {
3782fe8fb19SBen Gras 	int m, j;
3792fe8fb19SBen Gras 	double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0;
3802fe8fb19SBen Gras 	volatile double u1;
3812fe8fb19SBen Gras 
3822fe8fb19SBen Gras 	/* Catch special cases */
3832fe8fb19SBen Gras 	if (x <= 0) {
3842fe8fb19SBen Gras 		if (_IEEE && x == zero)	/* log(0) = -Inf */
3852fe8fb19SBen Gras 			return (-one/zero);
3862fe8fb19SBen Gras 		else if (_IEEE)		/* log(neg) = NaN */
3872fe8fb19SBen Gras 			return (zero/zero);
3882fe8fb19SBen Gras 		else if (x == zero)	/* NOT REACHED IF _IEEE */
3892fe8fb19SBen Gras 			return (infnan(-ERANGE));
3902fe8fb19SBen Gras 		else
3912fe8fb19SBen Gras 			return (infnan(EDOM));
3922fe8fb19SBen Gras 	} else if (!finite(x)) {
3932fe8fb19SBen Gras 		if (_IEEE)		/* x = NaN, Inf */
3942fe8fb19SBen Gras 			return (x+x);
3952fe8fb19SBen Gras 		else
3962fe8fb19SBen Gras 			return (infnan(ERANGE));
3972fe8fb19SBen Gras 	}
3982fe8fb19SBen Gras 
3992fe8fb19SBen Gras 	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
4002fe8fb19SBen Gras 	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
4012fe8fb19SBen Gras 
4022fe8fb19SBen Gras 	m = logb(x);
4032fe8fb19SBen Gras 	g = ldexp(x, -m);
4042fe8fb19SBen Gras 	if (_IEEE && m == -1022) {
4052fe8fb19SBen Gras 		j = logb(g), m += j;
4062fe8fb19SBen Gras 		g = ldexp(g, -j);
4072fe8fb19SBen Gras 	}
4082fe8fb19SBen Gras 	j = N*(g-1) + .5;
4092fe8fb19SBen Gras 	F = (1.0/N) * j + 1;	/* F*128 is an integer in [128, 512] */
4102fe8fb19SBen Gras 	f = g - F;
4112fe8fb19SBen Gras 
4122fe8fb19SBen Gras 	/* Approximate expansion for log(1+f/F) ~= u + q */
4132fe8fb19SBen Gras 	g = 1/(2*F+f);
4142fe8fb19SBen Gras 	u = 2*f*g;
4152fe8fb19SBen Gras 	v = u*u;
4162fe8fb19SBen Gras 	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
4172fe8fb19SBen Gras 
4182fe8fb19SBen Gras     /* case 1: u1 = u rounded to 2^-43 absolute.  Since u < 2^-8,
4192fe8fb19SBen Gras      * 	       u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits.
4202fe8fb19SBen Gras      *         It also adds exactly to |m*log2_hi + log_F_head[j] | < 750
4212fe8fb19SBen Gras     */
4222fe8fb19SBen Gras 	if (m | j)
4232fe8fb19SBen Gras 		u1 = u + 513, u1 -= 513;
4242fe8fb19SBen Gras 
4252fe8fb19SBen Gras     /* case 2:	|1-x| < 1/256. The m- and j- dependent terms are zero;
4262fe8fb19SBen Gras      * 		u1 = u to 24 bits.
4272fe8fb19SBen Gras     */
4282fe8fb19SBen Gras 	else
4292fe8fb19SBen Gras 		u1 = u, TRUNC(u1);
4302fe8fb19SBen Gras 	u2 = (2.0*(f - F*u1) - u1*f) * g;
4312fe8fb19SBen Gras 			/* u1 + u2 = 2f/(2F+f) to extra precision.	*/
4322fe8fb19SBen Gras 
4332fe8fb19SBen Gras 	/* log(x) = log(2^m*F*(1+f/F)) =				*/
4342fe8fb19SBen Gras 	/* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q);	*/
4352fe8fb19SBen Gras 	/* (exact) + (tiny)						*/
4362fe8fb19SBen Gras 
4372fe8fb19SBen Gras 	u1 += m*logF_head[N] + logF_head[j];		/* exact */
4382fe8fb19SBen Gras 	u2 = (u2 + logF_tail[j]) + q;			/* tiny */
4392fe8fb19SBen Gras 	u2 += logF_tail[N]*m;
4402fe8fb19SBen Gras 	return (u1 + u2);
4412fe8fb19SBen Gras }
4422fe8fb19SBen Gras 
4432fe8fb19SBen Gras /*
4442fe8fb19SBen Gras  * Extra precision variant, returning struct {double a, b;};
4452fe8fb19SBen Gras  * log(x) = a+b to 63 bits, with a is rounded to 26 bits.
4462fe8fb19SBen Gras  */
4472fe8fb19SBen Gras struct Double
__log__D(double x)4482fe8fb19SBen Gras __log__D(double x)
4492fe8fb19SBen Gras {
4502fe8fb19SBen Gras 	int m, j;
4512fe8fb19SBen Gras 	double F, f, g, q, u, v, u2;
4522fe8fb19SBen Gras 	volatile double u1;
4532fe8fb19SBen Gras 	struct Double r;
4542fe8fb19SBen Gras 
4552fe8fb19SBen Gras 	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
4562fe8fb19SBen Gras 	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
4572fe8fb19SBen Gras 
4582fe8fb19SBen Gras 	m = logb(x);
4592fe8fb19SBen Gras 	g = ldexp(x, -m);
4602fe8fb19SBen Gras 	if (_IEEE && m == -1022) {
4612fe8fb19SBen Gras 		j = logb(g), m += j;
4622fe8fb19SBen Gras 		g = ldexp(g, -j);
4632fe8fb19SBen Gras 	}
4642fe8fb19SBen Gras 	j = N*(g-1) + .5;
4652fe8fb19SBen Gras 	F = (1.0/N) * j + 1;
4662fe8fb19SBen Gras 	f = g - F;
4672fe8fb19SBen Gras 
4682fe8fb19SBen Gras 	g = 1/(2*F+f);
4692fe8fb19SBen Gras 	u = 2*f*g;
4702fe8fb19SBen Gras 	v = u*u;
4712fe8fb19SBen Gras 	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
4722fe8fb19SBen Gras 	if (m | j)
4732fe8fb19SBen Gras 		u1 = u + 513, u1 -= 513;
4742fe8fb19SBen Gras 	else
4752fe8fb19SBen Gras 		u1 = u, TRUNC(u1);
4762fe8fb19SBen Gras 	u2 = (2.0*(f - F*u1) - u1*f) * g;
4772fe8fb19SBen Gras 
4782fe8fb19SBen Gras 	u1 += m*logF_head[N] + logF_head[j];
4792fe8fb19SBen Gras 
4802fe8fb19SBen Gras 	u2 +=  logF_tail[j]; u2 += q;
4812fe8fb19SBen Gras 	u2 += logF_tail[N]*m;
4822fe8fb19SBen Gras 	r.a = u1 + u2;			/* Only difference is here */
4832fe8fb19SBen Gras 	TRUNC(r.a);
4842fe8fb19SBen Gras 	r.b = (u1 - r.a) + u2;
4852fe8fb19SBen Gras 	return (r);
4862fe8fb19SBen Gras }
4872fe8fb19SBen Gras 
4882fe8fb19SBen Gras float
logf(float x)4892fe8fb19SBen Gras logf(float x)
4902fe8fb19SBen Gras {
4912fe8fb19SBen Gras 	return(log((double)x));
4922fe8fb19SBen Gras }
493