Blame src/lib/libast/uwin/log.c

Packit Service a8c26c
#include "FEATURE/uwin"
Packit Service a8c26c
Packit Service a8c26c
#if !_UWIN
Packit Service a8c26c
Packit Service a8c26c
void _STUB_log(){}
Packit Service a8c26c
Packit Service a8c26c
#else
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * Copyright (c) 1992, 1993
Packit Service a8c26c
 *	The Regents of the University of California.  All rights reserved.
Packit Service a8c26c
 *
Packit Service a8c26c
 * Redistribution and use in source and binary forms, with or without
Packit Service a8c26c
 * modification, are permitted provided that the following conditions
Packit Service a8c26c
 * are met:
Packit Service a8c26c
 * 1. Redistributions of source code must retain the above copyright
Packit Service a8c26c
 *    notice, this list of conditions and the following disclaimer.
Packit Service a8c26c
 * 2. Redistributions in binary form must reproduce the above copyright
Packit Service a8c26c
 *    notice, this list of conditions and the following disclaimer in the
Packit Service a8c26c
 *    documentation and/or other materials provided with the distribution.
Packit Service a8c26c
 * 3. Neither the name of the University nor the names of its contributors
Packit Service a8c26c
 *    may be used to endorse or promote products derived from this software
Packit Service a8c26c
 *    without specific prior written permission.
Packit Service a8c26c
 *
Packit Service a8c26c
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
Packit Service a8c26c
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit Service a8c26c
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit Service a8c26c
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
Packit Service a8c26c
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service a8c26c
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit Service a8c26c
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit Service a8c26c
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit Service a8c26c
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit Service a8c26c
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit Service a8c26c
 * SUCH DAMAGE.
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#ifndef lint
Packit Service a8c26c
static char sccsid[] = "@(#)log.c	8.2 (Berkeley) 11/30/93";
Packit Service a8c26c
#endif /* not lint */
Packit Service a8c26c
Packit Service a8c26c
#include <math.h>
Packit Service a8c26c
#include <errno.h>
Packit Service a8c26c
Packit Service a8c26c
#include "mathimpl.h"
Packit Service a8c26c
Packit Service a8c26c
/* Table-driven natural logarithm.
Packit Service a8c26c
 *
Packit Service a8c26c
 * This code was derived, with minor modifications, from:
Packit Service a8c26c
 *	Peter Tang, "Table-Driven Implementation of the
Packit Service a8c26c
 *	Logarithm in IEEE Floating-Point arithmetic." ACM Trans.
Packit Service a8c26c
 *	Math Software, vol 16. no 4, pp 378-400, Dec 1990).
Packit Service a8c26c
 *
Packit Service a8c26c
 * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256,
Packit Service a8c26c
 * where F = j/128 for j an integer in [0, 128].
Packit Service a8c26c
 *
Packit Service a8c26c
 * log(2^m) = log2_hi*m + log2_tail*m
Packit Service a8c26c
 * since m is an integer, the dominant term is exact.
Packit Service a8c26c
 * m has at most 10 digits (for subnormal numbers),
Packit Service a8c26c
 * and log2_hi has 11 trailing zero bits.
Packit Service a8c26c
 *
Packit Service a8c26c
 * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h
Packit Service a8c26c
 * logF_hi[] + 512 is exact.
Packit Service a8c26c
 *
Packit Service a8c26c
 * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ...
Packit Service a8c26c
 * the leading term is calculated to extra precision in two
Packit Service a8c26c
 * parts, the larger of which adds exactly to the dominant
Packit Service a8c26c
 * m and F terms.
Packit Service a8c26c
 * There are two cases:
Packit Service a8c26c
 *	1. when m, j are non-zero (m | j), use absolute
Packit Service a8c26c
 *	   precision for the leading term.
Packit Service a8c26c
 *	2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
Packit Service a8c26c
 *	   In this case, use a relative precision of 24 bits.
Packit Service a8c26c
 * (This is done differently in the original paper)
Packit Service a8c26c
 *
Packit Service a8c26c
 * Special cases:
Packit Service a8c26c
 *	0	return signalling -Inf
Packit Service a8c26c
 *	neg	return signalling NaN
Packit Service a8c26c
 *	+Inf	return +Inf
Packit Service a8c26c
*/
Packit Service a8c26c
Packit Service a8c26c
#if defined(vax) || defined(tahoe)
Packit Service a8c26c
#define _IEEE		0
Packit Service a8c26c
#define TRUNC(x)	x = (double) (float) (x)
Packit Service a8c26c
#else
Packit Service a8c26c
#define _IEEE		1
Packit Service a8c26c
#define endian		(((*(int *) &one)) ? 1 : 0)
Packit Service a8c26c
#define TRUNC(x)	*(((int *) &x) + endian) &= 0xf8000000
Packit Service a8c26c
#define infnan(x)	0.0
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#define N 128
Packit Service a8c26c
Packit Service a8c26c
/* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
Packit Service a8c26c
 * Used for generation of extend precision logarithms.
Packit Service a8c26c
 * The constant 35184372088832 is 2^45, so the divide is exact.
Packit Service a8c26c
 * It ensures correct reading of logF_head, even for inaccurate
Packit Service a8c26c
 * decimal-to-binary conversion routines.  (Everybody gets the
Packit Service a8c26c
 * right answer for integers less than 2^53.)
Packit Service a8c26c
 * Values for log(F) were generated using error < 10^-57 absolute
Packit Service a8c26c
 * with the bc -l package.
Packit Service a8c26c
*/
Packit Service a8c26c
static double	A1 = 	  .08333333333333178827;
Packit Service a8c26c
static double	A2 = 	  .01250000000377174923;
Packit Service a8c26c
static double	A3 =	 .002232139987919447809;
Packit Service a8c26c
static double	A4 =	.0004348877777076145742;
Packit Service a8c26c
Packit Service a8c26c
static double logF_head[N+1] = {
Packit Service a8c26c
	0.,
Packit Service a8c26c
	.007782140442060381246,
Packit Service a8c26c
	.015504186535963526694,
Packit Service a8c26c
	.023167059281547608406,
Packit Service a8c26c
	.030771658666765233647,
Packit Service a8c26c
	.038318864302141264488,
Packit Service a8c26c
	.045809536031242714670,
Packit Service a8c26c
	.053244514518837604555,
Packit Service a8c26c
	.060624621816486978786,
Packit Service a8c26c
	.067950661908525944454,
Packit Service a8c26c
	.075223421237524235039,
Packit Service a8c26c
	.082443669210988446138,
Packit Service a8c26c
	.089612158689760690322,
Packit Service a8c26c
	.096729626458454731618,
Packit Service a8c26c
	.103796793681567578460,
Packit Service a8c26c
	.110814366340264314203,
Packit Service a8c26c
	.117783035656430001836,
Packit Service a8c26c
	.124703478501032805070,
Packit Service a8c26c
	.131576357788617315236,
Packit Service a8c26c
	.138402322859292326029,
Packit Service a8c26c
	.145182009844575077295,
Packit Service a8c26c
	.151916042025732167530,
Packit Service a8c26c
	.158605030176659056451,
Packit Service a8c26c
	.165249572895390883786,
Packit Service a8c26c
	.171850256926518341060,
Packit Service a8c26c
	.178407657472689606947,
Packit Service a8c26c
	.184922338493834104156,
Packit Service a8c26c
	.191394852999565046047,
Packit Service a8c26c
	.197825743329758552135,
Packit Service a8c26c
	.204215541428766300668,
Packit Service a8c26c
	.210564769107350002741,
Packit Service a8c26c
	.216873938300523150246,
Packit Service a8c26c
	.223143551314024080056,
Packit Service a8c26c
	.229374101064877322642,
Packit Service a8c26c
	.235566071312860003672,
Packit Service a8c26c
	.241719936886966024758,
Packit Service a8c26c
	.247836163904594286577,
Packit Service a8c26c
	.253915209980732470285,
Packit Service a8c26c
	.259957524436686071567,
Packit Service a8c26c
	.265963548496984003577,
Packit Service a8c26c
	.271933715484010463114,
Packit Service a8c26c
	.277868451003087102435,
Packit Service a8c26c
	.283768173130738432519,
Packit Service a8c26c
	.289633292582948342896,
Packit Service a8c26c
	.295464212893421063199,
Packit Service a8c26c
	.301261330578199704177,
Packit Service a8c26c
	.307025035294827830512,
Packit Service a8c26c
	.312755710004239517729,
Packit Service a8c26c
	.318453731118097493890,
Packit Service a8c26c
	.324119468654316733591,
Packit Service a8c26c
	.329753286372579168528,
Packit Service a8c26c
	.335355541920762334484,
Packit Service a8c26c
	.340926586970454081892,
Packit Service a8c26c
	.346466767346100823488,
Packit Service a8c26c
	.351976423156884266063,
Packit Service a8c26c
	.357455888922231679316,
Packit Service a8c26c
	.362905493689140712376,
Packit Service a8c26c
	.368325561158599157352,
Packit Service a8c26c
	.373716409793814818840,
Packit Service a8c26c
	.379078352934811846353,
Packit Service a8c26c
	.384411698910298582632,
Packit Service a8c26c
	.389716751140440464951,
Packit Service a8c26c
	.394993808240542421117,
Packit Service a8c26c
	.400243164127459749579,
Packit Service a8c26c
	.405465108107819105498,
Packit Service a8c26c
	.410659924985338875558,
Packit Service a8c26c
	.415827895143593195825,
Packit Service a8c26c
	.420969294644237379543,
Packit Service a8c26c
	.426084395310681429691,
Packit Service a8c26c
	.431173464818130014464,
Packit Service a8c26c
	.436236766774527495726,
Packit Service a8c26c
	.441274560805140936281,
Packit Service a8c26c
	.446287102628048160113,
Packit Service a8c26c
	.451274644139630254358,
Packit Service a8c26c
	.456237433481874177232,
Packit Service a8c26c
	.461175715122408291790,
Packit Service a8c26c
	.466089729924533457960,
Packit Service a8c26c
	.470979715219073113985,
Packit Service a8c26c
	.475845904869856894947,
Packit Service a8c26c
	.480688529345570714212,
Packit Service a8c26c
	.485507815781602403149,
Packit Service a8c26c
	.490303988045525329653,
Packit Service a8c26c
	.495077266798034543171,
Packit Service a8c26c
	.499827869556611403822,
Packit Service a8c26c
	.504556010751912253908,
Packit Service a8c26c
	.509261901790523552335,
Packit Service a8c26c
	.513945751101346104405,
Packit Service a8c26c
	.518607764208354637958,
Packit Service a8c26c
	.523248143765158602036,
Packit Service a8c26c
	.527867089620485785417,
Packit Service a8c26c
	.532464798869114019908,
Packit Service a8c26c
	.537041465897345915436,
Packit Service a8c26c
	.541597282432121573947,
Packit Service a8c26c
	.546132437597407260909,
Packit Service a8c26c
	.550647117952394182793,
Packit Service a8c26c
	.555141507540611200965,
Packit Service a8c26c
	.559615787935399566777,
Packit Service a8c26c
	.564070138285387656651,
Packit Service a8c26c
	.568504735352689749561,
Packit Service a8c26c
	.572919753562018740922,
Packit Service a8c26c
	.577315365035246941260,
Packit Service a8c26c
	.581691739635061821900,
Packit Service a8c26c
	.586049045003164792433,
Packit Service a8c26c
	.590387446602107957005,
Packit Service a8c26c
	.594707107746216934174,
Packit Service a8c26c
	.599008189645246602594,
Packit Service a8c26c
	.603290851438941899687,
Packit Service a8c26c
	.607555250224322662688,
Packit Service a8c26c
	.611801541106615331955,
Packit Service a8c26c
	.616029877215623855590,
Packit Service a8c26c
	.620240409751204424537,
Packit Service a8c26c
	.624433288012369303032,
Packit Service a8c26c
	.628608659422752680256,
Packit Service a8c26c
	.632766669570628437213,
Packit Service a8c26c
	.636907462236194987781,
Packit Service a8c26c
	.641031179420679109171,
Packit Service a8c26c
	.645137961373620782978,
Packit Service a8c26c
	.649227946625615004450,
Packit Service a8c26c
	.653301272011958644725,
Packit Service a8c26c
	.657358072709030238911,
Packit Service a8c26c
	.661398482245203922502,
Packit Service a8c26c
	.665422632544505177065,
Packit Service a8c26c
	.669430653942981734871,
Packit Service a8c26c
	.673422675212350441142,
Packit Service a8c26c
	.677398823590920073911,
Packit Service a8c26c
	.681359224807238206267,
Packit Service a8c26c
	.685304003098281100392,
Packit Service a8c26c
	.689233281238557538017,
Packit Service a8c26c
	.693147180560117703862
Packit Service a8c26c
};
Packit Service a8c26c
Packit Service a8c26c
static double logF_tail[N+1] = {
Packit Service a8c26c
	0.,
Packit Service a8c26c
	-.00000000000000543229938420049,
Packit Service a8c26c
	 .00000000000000172745674997061,
Packit Service a8c26c
	-.00000000000001323017818229233,
Packit Service a8c26c
	-.00000000000001154527628289872,
Packit Service a8c26c
	-.00000000000000466529469958300,
Packit Service a8c26c
	 .00000000000005148849572685810,
Packit Service a8c26c
	-.00000000000002532168943117445,
Packit Service a8c26c
	-.00000000000005213620639136504,
Packit Service a8c26c
	-.00000000000001819506003016881,
Packit Service a8c26c
	 .00000000000006329065958724544,
Packit Service a8c26c
	 .00000000000008614512936087814,
Packit Service a8c26c
	-.00000000000007355770219435028,
Packit Service a8c26c
	 .00000000000009638067658552277,
Packit Service a8c26c
	 .00000000000007598636597194141,
Packit Service a8c26c
	 .00000000000002579999128306990,
Packit Service a8c26c
	-.00000000000004654729747598444,
Packit Service a8c26c
	-.00000000000007556920687451336,
Packit Service a8c26c
	 .00000000000010195735223708472,
Packit Service a8c26c
	-.00000000000017319034406422306,
Packit Service a8c26c
	-.00000000000007718001336828098,
Packit Service a8c26c
	 .00000000000010980754099855238,
Packit Service a8c26c
	-.00000000000002047235780046195,
Packit Service a8c26c
	-.00000000000008372091099235912,
Packit Service a8c26c
	 .00000000000014088127937111135,
Packit Service a8c26c
	 .00000000000012869017157588257,
Packit Service a8c26c
	 .00000000000017788850778198106,
Packit Service a8c26c
	 .00000000000006440856150696891,
Packit Service a8c26c
	 .00000000000016132822667240822,
Packit Service a8c26c
	-.00000000000007540916511956188,
Packit Service a8c26c
	-.00000000000000036507188831790,
Packit Service a8c26c
	 .00000000000009120937249914984,
Packit Service a8c26c
	 .00000000000018567570959796010,
Packit Service a8c26c
	-.00000000000003149265065191483,
Packit Service a8c26c
	-.00000000000009309459495196889,
Packit Service a8c26c
	 .00000000000017914338601329117,
Packit Service a8c26c
	-.00000000000001302979717330866,
Packit Service a8c26c
	 .00000000000023097385217586939,
Packit Service a8c26c
	 .00000000000023999540484211737,
Packit Service a8c26c
	 .00000000000015393776174455408,
Packit Service a8c26c
	-.00000000000036870428315837678,
Packit Service a8c26c
	 .00000000000036920375082080089,
Packit Service a8c26c
	-.00000000000009383417223663699,
Packit Service a8c26c
	 .00000000000009433398189512690,
Packit Service a8c26c
	 .00000000000041481318704258568,
Packit Service a8c26c
	-.00000000000003792316480209314,
Packit Service a8c26c
	 .00000000000008403156304792424,
Packit Service a8c26c
	-.00000000000034262934348285429,
Packit Service a8c26c
	 .00000000000043712191957429145,
Packit Service a8c26c
	-.00000000000010475750058776541,
Packit Service a8c26c
	-.00000000000011118671389559323,
Packit Service a8c26c
	 .00000000000037549577257259853,
Packit Service a8c26c
	 .00000000000013912841212197565,
Packit Service a8c26c
	 .00000000000010775743037572640,
Packit Service a8c26c
	 .00000000000029391859187648000,
Packit Service a8c26c
	-.00000000000042790509060060774,
Packit Service a8c26c
	 .00000000000022774076114039555,
Packit Service a8c26c
	 .00000000000010849569622967912,
Packit Service a8c26c
	-.00000000000023073801945705758,
Packit Service a8c26c
	 .00000000000015761203773969435,
Packit Service a8c26c
	 .00000000000003345710269544082,
Packit Service a8c26c
	-.00000000000041525158063436123,
Packit Service a8c26c
	 .00000000000032655698896907146,
Packit Service a8c26c
	-.00000000000044704265010452446,
Packit Service a8c26c
	 .00000000000034527647952039772,
Packit Service a8c26c
	-.00000000000007048962392109746,
Packit Service a8c26c
	 .00000000000011776978751369214,
Packit Service a8c26c
	-.00000000000010774341461609578,
Packit Service a8c26c
	 .00000000000021863343293215910,
Packit Service a8c26c
	 .00000000000024132639491333131,
Packit Service a8c26c
	 .00000000000039057462209830700,
Packit Service a8c26c
	-.00000000000026570679203560751,
Packit Service a8c26c
	 .00000000000037135141919592021,
Packit Service a8c26c
	-.00000000000017166921336082431,
Packit Service a8c26c
	-.00000000000028658285157914353,
Packit Service a8c26c
	-.00000000000023812542263446809,
Packit Service a8c26c
	 .00000000000006576659768580062,
Packit Service a8c26c
	-.00000000000028210143846181267,
Packit Service a8c26c
	 .00000000000010701931762114254,
Packit Service a8c26c
	 .00000000000018119346366441110,
Packit Service a8c26c
	 .00000000000009840465278232627,
Packit Service a8c26c
	-.00000000000033149150282752542,
Packit Service a8c26c
	-.00000000000018302857356041668,
Packit Service a8c26c
	-.00000000000016207400156744949,
Packit Service a8c26c
	 .00000000000048303314949553201,
Packit Service a8c26c
	-.00000000000071560553172382115,
Packit Service a8c26c
	 .00000000000088821239518571855,
Packit Service a8c26c
	-.00000000000030900580513238244,
Packit Service a8c26c
	-.00000000000061076551972851496,
Packit Service a8c26c
	 .00000000000035659969663347830,
Packit Service a8c26c
	 .00000000000035782396591276383,
Packit Service a8c26c
	-.00000000000046226087001544578,
Packit Service a8c26c
	 .00000000000062279762917225156,
Packit Service a8c26c
	 .00000000000072838947272065741,
Packit Service a8c26c
	 .00000000000026809646615211673,
Packit Service a8c26c
	-.00000000000010960825046059278,
Packit Service a8c26c
	 .00000000000002311949383800537,
Packit Service a8c26c
	-.00000000000058469058005299247,
Packit Service a8c26c
	-.00000000000002103748251144494,
Packit Service a8c26c
	-.00000000000023323182945587408,
Packit Service a8c26c
	-.00000000000042333694288141916,
Packit Service a8c26c
	-.00000000000043933937969737844,
Packit Service a8c26c
	 .00000000000041341647073835565,
Packit Service a8c26c
	 .00000000000006841763641591466,
Packit Service a8c26c
	 .00000000000047585534004430641,
Packit Service a8c26c
	 .00000000000083679678674757695,
Packit Service a8c26c
	-.00000000000085763734646658640,
Packit Service a8c26c
	 .00000000000021913281229340092,
Packit Service a8c26c
	-.00000000000062242842536431148,
Packit Service a8c26c
	-.00000000000010983594325438430,
Packit Service a8c26c
	 .00000000000065310431377633651,
Packit Service a8c26c
	-.00000000000047580199021710769,
Packit Service a8c26c
	-.00000000000037854251265457040,
Packit Service a8c26c
	 .00000000000040939233218678664,
Packit Service a8c26c
	 .00000000000087424383914858291,
Packit Service a8c26c
	 .00000000000025218188456842882,
Packit Service a8c26c
	-.00000000000003608131360422557,
Packit Service a8c26c
	-.00000000000050518555924280902,
Packit Service a8c26c
	 .00000000000078699403323355317,
Packit Service a8c26c
	-.00000000000067020876961949060,
Packit Service a8c26c
	 .00000000000016108575753932458,
Packit Service a8c26c
	 .00000000000058527188436251509,
Packit Service a8c26c
	-.00000000000035246757297904791,
Packit Service a8c26c
	-.00000000000018372084495629058,
Packit Service a8c26c
	 .00000000000088606689813494916,
Packit Service a8c26c
	 .00000000000066486268071468700,
Packit Service a8c26c
	 .00000000000063831615170646519,
Packit Service a8c26c
	 .00000000000025144230728376072,
Packit Service a8c26c
	-.00000000000017239444525614834
Packit Service a8c26c
};
Packit Service a8c26c
Packit Service a8c26c
#if !_lib_log
Packit Service a8c26c
Packit Service a8c26c
extern double
Packit Service a8c26c
#ifdef _ANSI_SOURCE
Packit Service a8c26c
log(double x)
Packit Service a8c26c
#else
Packit Service a8c26c
log(x) double x;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	int m, j;
Packit Service a8c26c
	double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0;
Packit Service a8c26c
	volatile double u1;
Packit Service a8c26c
Packit Service a8c26c
	/* Catch special cases */
Packit Service a8c26c
	if (x <= 0)
Packit Service a8c26c
		if (_IEEE && x == zero)	/* log(0) = -Inf */
Packit Service a8c26c
			return (-one/zero);
Packit Service a8c26c
		else if (_IEEE)		/* log(neg) = NaN */
Packit Service a8c26c
			return (zero/zero);
Packit Service a8c26c
		else if (x == zero)	/* NOT REACHED IF _IEEE */
Packit Service a8c26c
			return (infnan(-ERANGE));
Packit Service a8c26c
		else
Packit Service a8c26c
			return (infnan(EDOM));
Packit Service a8c26c
	else if (!finite(x))
Packit Service a8c26c
		if (_IEEE)		/* x = NaN, Inf */
Packit Service a8c26c
			return (x+x);
Packit Service a8c26c
		else
Packit Service a8c26c
			return (infnan(ERANGE));
Packit Service a8c26c
	
Packit Service a8c26c
	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
Packit Service a8c26c
	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
Packit Service a8c26c
Packit Service a8c26c
	m = logb(x);
Packit Service a8c26c
	g = ldexp(x, -m);
Packit Service a8c26c
	if (_IEEE && m == -1022) {
Packit Service a8c26c
		j = logb(g), m += j;
Packit Service a8c26c
		g = ldexp(g, -j);
Packit Service a8c26c
	}
Packit Service a8c26c
	j = N*(g-1) + .5;
Packit Service a8c26c
	F = (1.0/N) * j + 1;	/* F*128 is an integer in [128, 512] */
Packit Service a8c26c
	f = g - F;
Packit Service a8c26c
Packit Service a8c26c
	/* Approximate expansion for log(1+f/F) ~= u + q */
Packit Service a8c26c
	g = 1/(2*F+f);
Packit Service a8c26c
	u = 2*f*g;
Packit Service a8c26c
	v = u*u;
Packit Service a8c26c
	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
Packit Service a8c26c
Packit Service a8c26c
    /* case 1: u1 = u rounded to 2^-43 absolute.  Since u < 2^-8,
Packit Service a8c26c
     * 	       u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits.
Packit Service a8c26c
     *         It also adds exactly to |m*log2_hi + log_F_head[j] | < 750
Packit Service a8c26c
    */
Packit Service a8c26c
	if (m | j)
Packit Service a8c26c
		u1 = u + 513, u1 -= 513;
Packit Service a8c26c
Packit Service a8c26c
    /* case 2:	|1-x| < 1/256. The m- and j- dependent terms are zero;
Packit Service a8c26c
     * 		u1 = u to 24 bits.
Packit Service a8c26c
    */
Packit Service a8c26c
	else
Packit Service a8c26c
		u1 = u, TRUNC(u1);
Packit Service a8c26c
	u2 = (2.0*(f - F*u1) - u1*f) * g;
Packit Service a8c26c
			/* u1 + u2 = 2f/(2F+f) to extra precision.	*/
Packit Service a8c26c
Packit Service a8c26c
	/* log(x) = log(2^m*F*(1+f/F)) =				*/
Packit Service a8c26c
	/* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q);	*/
Packit Service a8c26c
	/* (exact) + (tiny)						*/
Packit Service a8c26c
Packit Service a8c26c
	u1 += m*logF_head[N] + logF_head[j];		/* exact */
Packit Service a8c26c
	u2 = (u2 + logF_tail[j]) + q;			/* tiny */
Packit Service a8c26c
	u2 += logF_tail[N]*m;
Packit Service a8c26c
	return (u1 + u2);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * Extra precision variant, returning struct {double a, b;};
Packit Service a8c26c
 * log(x) = a+b to 63 bits, with a is rounded to 26 bits.
Packit Service a8c26c
 */
Packit Service a8c26c
struct Double
Packit Service a8c26c
#ifdef _ANSI_SOURCE
Packit Service a8c26c
__log__D(double x)
Packit Service a8c26c
#else
Packit Service a8c26c
__log__D(x) double x;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	int m, j;
Packit Service a8c26c
	double F, f, g, q, u, v, u2, one = 1.0;
Packit Service a8c26c
	volatile double u1;
Packit Service a8c26c
	struct Double r;
Packit Service a8c26c
Packit Service a8c26c
	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
Packit Service a8c26c
	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
Packit Service a8c26c
Packit Service a8c26c
	m = (int)logb(x);
Packit Service a8c26c
	g = ldexp(x, -m);
Packit Service a8c26c
	if (_IEEE && m == -1022) {
Packit Service a8c26c
		j = (int)logb(g), m += j;
Packit Service a8c26c
		g = ldexp(g, -j);
Packit Service a8c26c
	}
Packit Service a8c26c
	j = (int)(N*(g-1) + .5);
Packit Service a8c26c
	F = (1.0/N) * j + 1;
Packit Service a8c26c
	f = g - F;
Packit Service a8c26c
Packit Service a8c26c
	g = 1/(2*F+f);
Packit Service a8c26c
	u = 2*f*g;
Packit Service a8c26c
	v = u*u;
Packit Service a8c26c
	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
Packit Service a8c26c
	if (m | j)
Packit Service a8c26c
		u1 = u + 513, u1 -= 513;
Packit Service a8c26c
	else
Packit Service a8c26c
		u1 = u, TRUNC(u1);
Packit Service a8c26c
	u2 = (2.0*(f - F*u1) - u1*f) * g;
Packit Service a8c26c
Packit Service a8c26c
	u1 += m*logF_head[N] + logF_head[j];
Packit Service a8c26c
Packit Service a8c26c
	u2 +=  logF_tail[j]; u2 += q;
Packit Service a8c26c
	u2 += logF_tail[N]*m;
Packit Service a8c26c
	r.a = u1 + u2;			/* Only difference is here */
Packit Service a8c26c
	TRUNC(r.a);
Packit Service a8c26c
	r.b = (u1 - r.a) + u2;
Packit Service a8c26c
	return (r);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif