xref: /csrg-svn/lib/libm/common_source/log.c (revision 64992)
134126Sbostic /*
261309Sbostic  * Copyright (c) 1992, 1993
361309Sbostic  *	The Regents of the University of California.  All rights reserved.
434126Sbostic  *
542657Sbostic  * %sccs.include.redist.c%
624601Szliu  */
724601Szliu 
824601Szliu #ifndef lint
9*64992Smckusick static char sccsid[] = "@(#)log.c	8.2 (Berkeley) 11/30/93";
1034126Sbostic #endif /* not lint */
1124601Szliu 
1256955Sbostic #include <math.h>
1356955Sbostic #include <errno.h>
1456955Sbostic 
1557158Smcilroy #include "mathimpl.h"
1656955Sbostic 
1756955Sbostic /* Table-driven natural logarithm.
1824601Szliu  *
1956955Sbostic  * This code was derived, with minor modifications, from:
2056955Sbostic  *	Peter Tang, "Table-Driven Implementation of the
2156955Sbostic  *	Logarithm in IEEE Floating-Point arithmetic." ACM Trans.
2256955Sbostic  *	Math Software, vol 16. no 4, pp 378-400, Dec 1990).
2324601Szliu  *
2456955Sbostic  * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256,
2556955Sbostic  * where F = j/128 for j an integer in [0, 128].
2624601Szliu  *
2756955Sbostic  * log(2^m) = log2_hi*m + log2_tail*m
2856955Sbostic  * since m is an integer, the dominant term is exact.
2956955Sbostic  * m has at most 10 digits (for subnormal numbers),
3056955Sbostic  * and log2_hi has 11 trailing zero bits.
3124601Szliu  *
3256955Sbostic  * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h
3356955Sbostic  * logF_hi[] + 512 is exact.
3424601Szliu  *
3556955Sbostic  * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ...
3656955Sbostic  * the leading term is calculated to extra precision in two
3756955Sbostic  * parts, the larger of which adds exactly to the dominant
3856955Sbostic  * m and F terms.
3956955Sbostic  * There are two cases:
4056955Sbostic  *	1. when m, j are non-zero (m | j), use absolute
4156955Sbostic  *	   precision for the leading term.
4256955Sbostic  *	2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
4356955Sbostic  *	   In this case, use a relative precision of 24 bits.
4456955Sbostic  * (This is done differently in the original paper)
4524601Szliu  *
4624601Szliu  * Special cases:
4756955Sbostic  *	0	return signalling -Inf
4856955Sbostic  *	neg	return signalling NaN
4956955Sbostic  *	+Inf	return +Inf
5056955Sbostic */
5124601Szliu 
5256955Sbostic #if defined(vax) || defined(tahoe)
5357156Smcilroy #define _IEEE		0
5457156Smcilroy #define TRUNC(x)	x = (double) (float) (x)
5556955Sbostic #else
5657442Sbostic #define _IEEE		1
5757156Smcilroy #define endian		(((*(int *) &one)) ? 1 : 0)
5857156Smcilroy #define TRUNC(x)	*(((int *) &x) + endian) &= 0xf8000000
5957156Smcilroy #define infnan(x)	0.0
6056955Sbostic #endif
6124601Szliu 
6257442Sbostic #define N 128
6357442Sbostic 
6457442Sbostic /* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
6557442Sbostic  * Used for generation of extend precision logarithms.
6657442Sbostic  * The constant 35184372088832 is 2^45, so the divide is exact.
6757442Sbostic  * It ensures correct reading of logF_head, even for inaccurate
6857442Sbostic  * decimal-to-binary conversion routines.  (Everybody gets the
6957442Sbostic  * right answer for integers less than 2^53.)
7057442Sbostic  * Values for log(F) were generated using error < 10^-57 absolute
7157442Sbostic  * with the bc -l package.
7257442Sbostic */
7357453Sbostic static double	A1 = 	  .08333333333333178827;
7457453Sbostic static double	A2 = 	  .01250000000377174923;
7557453Sbostic static double	A3 =	 .002232139987919447809;
7657453Sbostic static double	A4 =	.0004348877777076145742;
7757442Sbostic 
7857453Sbostic static double logF_head[N+1] = {
7957442Sbostic 	0.,
8057442Sbostic 	.007782140442060381246,
8157442Sbostic 	.015504186535963526694,
8257442Sbostic 	.023167059281547608406,
8357442Sbostic 	.030771658666765233647,
8457442Sbostic 	.038318864302141264488,
8557442Sbostic 	.045809536031242714670,
8657442Sbostic 	.053244514518837604555,
8757442Sbostic 	.060624621816486978786,
8857442Sbostic 	.067950661908525944454,
8957442Sbostic 	.075223421237524235039,
9057442Sbostic 	.082443669210988446138,
9157442Sbostic 	.089612158689760690322,
9257442Sbostic 	.096729626458454731618,
9357442Sbostic 	.103796793681567578460,
9457442Sbostic 	.110814366340264314203,
9557442Sbostic 	.117783035656430001836,
9657442Sbostic 	.124703478501032805070,
9757442Sbostic 	.131576357788617315236,
9857442Sbostic 	.138402322859292326029,
9957442Sbostic 	.145182009844575077295,
10057442Sbostic 	.151916042025732167530,
10157442Sbostic 	.158605030176659056451,
10257442Sbostic 	.165249572895390883786,
10357442Sbostic 	.171850256926518341060,
10457442Sbostic 	.178407657472689606947,
10557442Sbostic 	.184922338493834104156,
10657442Sbostic 	.191394852999565046047,
10757442Sbostic 	.197825743329758552135,
10857442Sbostic 	.204215541428766300668,
10957442Sbostic 	.210564769107350002741,
11057442Sbostic 	.216873938300523150246,
11157442Sbostic 	.223143551314024080056,
11257442Sbostic 	.229374101064877322642,
11357442Sbostic 	.235566071312860003672,
11457442Sbostic 	.241719936886966024758,
11557442Sbostic 	.247836163904594286577,
11657442Sbostic 	.253915209980732470285,
11757442Sbostic 	.259957524436686071567,
11857442Sbostic 	.265963548496984003577,
11957442Sbostic 	.271933715484010463114,
12057442Sbostic 	.277868451003087102435,
12157442Sbostic 	.283768173130738432519,
12257442Sbostic 	.289633292582948342896,
12357442Sbostic 	.295464212893421063199,
12457442Sbostic 	.301261330578199704177,
12557442Sbostic 	.307025035294827830512,
12657442Sbostic 	.312755710004239517729,
12757442Sbostic 	.318453731118097493890,
12857442Sbostic 	.324119468654316733591,
12957442Sbostic 	.329753286372579168528,
13057442Sbostic 	.335355541920762334484,
13157442Sbostic 	.340926586970454081892,
13257442Sbostic 	.346466767346100823488,
13357442Sbostic 	.351976423156884266063,
13457442Sbostic 	.357455888922231679316,
13557442Sbostic 	.362905493689140712376,
13657442Sbostic 	.368325561158599157352,
13757442Sbostic 	.373716409793814818840,
13857442Sbostic 	.379078352934811846353,
13957442Sbostic 	.384411698910298582632,
14057442Sbostic 	.389716751140440464951,
14157442Sbostic 	.394993808240542421117,
14257442Sbostic 	.400243164127459749579,
14357442Sbostic 	.405465108107819105498,
14457442Sbostic 	.410659924985338875558,
14557442Sbostic 	.415827895143593195825,
14657442Sbostic 	.420969294644237379543,
14757442Sbostic 	.426084395310681429691,
14857442Sbostic 	.431173464818130014464,
14957442Sbostic 	.436236766774527495726,
15057442Sbostic 	.441274560805140936281,
15157442Sbostic 	.446287102628048160113,
15257442Sbostic 	.451274644139630254358,
15357442Sbostic 	.456237433481874177232,
15457442Sbostic 	.461175715122408291790,
15557442Sbostic 	.466089729924533457960,
15657442Sbostic 	.470979715219073113985,
15757442Sbostic 	.475845904869856894947,
15857442Sbostic 	.480688529345570714212,
15957442Sbostic 	.485507815781602403149,
16057442Sbostic 	.490303988045525329653,
16157442Sbostic 	.495077266798034543171,
16257442Sbostic 	.499827869556611403822,
16357442Sbostic 	.504556010751912253908,
16457442Sbostic 	.509261901790523552335,
16557442Sbostic 	.513945751101346104405,
16657442Sbostic 	.518607764208354637958,
16757442Sbostic 	.523248143765158602036,
16857442Sbostic 	.527867089620485785417,
16957442Sbostic 	.532464798869114019908,
17057442Sbostic 	.537041465897345915436,
17157442Sbostic 	.541597282432121573947,
17257442Sbostic 	.546132437597407260909,
17357442Sbostic 	.550647117952394182793,
17457442Sbostic 	.555141507540611200965,
17557442Sbostic 	.559615787935399566777,
17657442Sbostic 	.564070138285387656651,
17757442Sbostic 	.568504735352689749561,
17857442Sbostic 	.572919753562018740922,
17957442Sbostic 	.577315365035246941260,
18057442Sbostic 	.581691739635061821900,
18157442Sbostic 	.586049045003164792433,
18257442Sbostic 	.590387446602107957005,
18357442Sbostic 	.594707107746216934174,
18457442Sbostic 	.599008189645246602594,
18557442Sbostic 	.603290851438941899687,
18657442Sbostic 	.607555250224322662688,
18757442Sbostic 	.611801541106615331955,
18857442Sbostic 	.616029877215623855590,
18957442Sbostic 	.620240409751204424537,
19057442Sbostic 	.624433288012369303032,
19157442Sbostic 	.628608659422752680256,
19257442Sbostic 	.632766669570628437213,
19357442Sbostic 	.636907462236194987781,
19457442Sbostic 	.641031179420679109171,
19557442Sbostic 	.645137961373620782978,
19657442Sbostic 	.649227946625615004450,
19757442Sbostic 	.653301272011958644725,
19857442Sbostic 	.657358072709030238911,
19957442Sbostic 	.661398482245203922502,
20057442Sbostic 	.665422632544505177065,
20157442Sbostic 	.669430653942981734871,
20257442Sbostic 	.673422675212350441142,
20357442Sbostic 	.677398823590920073911,
20457442Sbostic 	.681359224807238206267,
20557442Sbostic 	.685304003098281100392,
20657442Sbostic 	.689233281238557538017,
20757442Sbostic 	.693147180560117703862
20857442Sbostic };
20957442Sbostic 
21057453Sbostic static double logF_tail[N+1] = {
21157442Sbostic 	0.,
21257442Sbostic 	-.00000000000000543229938420049,
21357442Sbostic 	 .00000000000000172745674997061,
21457442Sbostic 	-.00000000000001323017818229233,
21557442Sbostic 	-.00000000000001154527628289872,
21657442Sbostic 	-.00000000000000466529469958300,
21757442Sbostic 	 .00000000000005148849572685810,
21857442Sbostic 	-.00000000000002532168943117445,
21957442Sbostic 	-.00000000000005213620639136504,
22057442Sbostic 	-.00000000000001819506003016881,
22157442Sbostic 	 .00000000000006329065958724544,
22257442Sbostic 	 .00000000000008614512936087814,
22357442Sbostic 	-.00000000000007355770219435028,
22457442Sbostic 	 .00000000000009638067658552277,
22557442Sbostic 	 .00000000000007598636597194141,
22657442Sbostic 	 .00000000000002579999128306990,
22757442Sbostic 	-.00000000000004654729747598444,
22857442Sbostic 	-.00000000000007556920687451336,
22957442Sbostic 	 .00000000000010195735223708472,
23057442Sbostic 	-.00000000000017319034406422306,
23157442Sbostic 	-.00000000000007718001336828098,
23257442Sbostic 	 .00000000000010980754099855238,
23357442Sbostic 	-.00000000000002047235780046195,
23457442Sbostic 	-.00000000000008372091099235912,
23557442Sbostic 	 .00000000000014088127937111135,
23657442Sbostic 	 .00000000000012869017157588257,
23757442Sbostic 	 .00000000000017788850778198106,
23857442Sbostic 	 .00000000000006440856150696891,
23957442Sbostic 	 .00000000000016132822667240822,
24057442Sbostic 	-.00000000000007540916511956188,
24157442Sbostic 	-.00000000000000036507188831790,
24257442Sbostic 	 .00000000000009120937249914984,
24357442Sbostic 	 .00000000000018567570959796010,
24457442Sbostic 	-.00000000000003149265065191483,
24557442Sbostic 	-.00000000000009309459495196889,
24657442Sbostic 	 .00000000000017914338601329117,
24757442Sbostic 	-.00000000000001302979717330866,
24857442Sbostic 	 .00000000000023097385217586939,
24957442Sbostic 	 .00000000000023999540484211737,
25057442Sbostic 	 .00000000000015393776174455408,
25157442Sbostic 	-.00000000000036870428315837678,
25257442Sbostic 	 .00000000000036920375082080089,
25357442Sbostic 	-.00000000000009383417223663699,
25457442Sbostic 	 .00000000000009433398189512690,
25557442Sbostic 	 .00000000000041481318704258568,
25657442Sbostic 	-.00000000000003792316480209314,
25757442Sbostic 	 .00000000000008403156304792424,
25857442Sbostic 	-.00000000000034262934348285429,
25957442Sbostic 	 .00000000000043712191957429145,
26057442Sbostic 	-.00000000000010475750058776541,
26157442Sbostic 	-.00000000000011118671389559323,
26257442Sbostic 	 .00000000000037549577257259853,
26357442Sbostic 	 .00000000000013912841212197565,
26457442Sbostic 	 .00000000000010775743037572640,
26557442Sbostic 	 .00000000000029391859187648000,
26657442Sbostic 	-.00000000000042790509060060774,
26757442Sbostic 	 .00000000000022774076114039555,
26857442Sbostic 	 .00000000000010849569622967912,
26957442Sbostic 	-.00000000000023073801945705758,
27057442Sbostic 	 .00000000000015761203773969435,
27157442Sbostic 	 .00000000000003345710269544082,
27257442Sbostic 	-.00000000000041525158063436123,
27357442Sbostic 	 .00000000000032655698896907146,
27457442Sbostic 	-.00000000000044704265010452446,
27557442Sbostic 	 .00000000000034527647952039772,
27657442Sbostic 	-.00000000000007048962392109746,
27757442Sbostic 	 .00000000000011776978751369214,
27857442Sbostic 	-.00000000000010774341461609578,
27957442Sbostic 	 .00000000000021863343293215910,
28057442Sbostic 	 .00000000000024132639491333131,
28157442Sbostic 	 .00000000000039057462209830700,
28257442Sbostic 	-.00000000000026570679203560751,
28357442Sbostic 	 .00000000000037135141919592021,
28457442Sbostic 	-.00000000000017166921336082431,
28557442Sbostic 	-.00000000000028658285157914353,
28657442Sbostic 	-.00000000000023812542263446809,
28757442Sbostic 	 .00000000000006576659768580062,
28857442Sbostic 	-.00000000000028210143846181267,
28957442Sbostic 	 .00000000000010701931762114254,
29057442Sbostic 	 .00000000000018119346366441110,
29157442Sbostic 	 .00000000000009840465278232627,
29257442Sbostic 	-.00000000000033149150282752542,
29357442Sbostic 	-.00000000000018302857356041668,
29457442Sbostic 	-.00000000000016207400156744949,
29557442Sbostic 	 .00000000000048303314949553201,
29657442Sbostic 	-.00000000000071560553172382115,
29757442Sbostic 	 .00000000000088821239518571855,
29857442Sbostic 	-.00000000000030900580513238244,
29957442Sbostic 	-.00000000000061076551972851496,
30057442Sbostic 	 .00000000000035659969663347830,
30157442Sbostic 	 .00000000000035782396591276383,
30257442Sbostic 	-.00000000000046226087001544578,
30357442Sbostic 	 .00000000000062279762917225156,
30457442Sbostic 	 .00000000000072838947272065741,
30557442Sbostic 	 .00000000000026809646615211673,
30657442Sbostic 	-.00000000000010960825046059278,
30757442Sbostic 	 .00000000000002311949383800537,
30857442Sbostic 	-.00000000000058469058005299247,
30957442Sbostic 	-.00000000000002103748251144494,
31057442Sbostic 	-.00000000000023323182945587408,
31157442Sbostic 	-.00000000000042333694288141916,
31257442Sbostic 	-.00000000000043933937969737844,
31357442Sbostic 	 .00000000000041341647073835565,
31457442Sbostic 	 .00000000000006841763641591466,
31557442Sbostic 	 .00000000000047585534004430641,
31657442Sbostic 	 .00000000000083679678674757695,
31757442Sbostic 	-.00000000000085763734646658640,
31857442Sbostic 	 .00000000000021913281229340092,
31957442Sbostic 	-.00000000000062242842536431148,
32057442Sbostic 	-.00000000000010983594325438430,
32157442Sbostic 	 .00000000000065310431377633651,
32257442Sbostic 	-.00000000000047580199021710769,
32357442Sbostic 	-.00000000000037854251265457040,
32457442Sbostic 	 .00000000000040939233218678664,
32557442Sbostic 	 .00000000000087424383914858291,
32657442Sbostic 	 .00000000000025218188456842882,
32757442Sbostic 	-.00000000000003608131360422557,
32857442Sbostic 	-.00000000000050518555924280902,
32957442Sbostic 	 .00000000000078699403323355317,
33057442Sbostic 	-.00000000000067020876961949060,
33157442Sbostic 	 .00000000000016108575753932458,
33257442Sbostic 	 .00000000000058527188436251509,
33357442Sbostic 	-.00000000000035246757297904791,
33457442Sbostic 	-.00000000000018372084495629058,
33557442Sbostic 	 .00000000000088606689813494916,
33657442Sbostic 	 .00000000000066486268071468700,
33757442Sbostic 	 .00000000000063831615170646519,
33857442Sbostic 	 .00000000000025144230728376072,
33957442Sbostic 	-.00000000000017239444525614834
34057442Sbostic };
34157442Sbostic 
34256955Sbostic double
34356955Sbostic #ifdef _ANSI_SOURCE
log(double x)34456955Sbostic log(double x)
34556955Sbostic #else
34656955Sbostic log(x) double x;
34756955Sbostic #endif
34856955Sbostic {
34956955Sbostic 	int m, j;
35056955Sbostic 	double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0;
35156955Sbostic 	volatile double u1;
35235679Sbostic 
35356955Sbostic 	/* Catch special cases */
35456955Sbostic 	if (x <= 0)
35556955Sbostic 		if (_IEEE && x == zero)	/* log(0) = -Inf */
35656955Sbostic 			return (-one/zero);
35756955Sbostic 		else if (_IEEE)		/* log(neg) = NaN */
35856955Sbostic 			return (zero/zero);
35956955Sbostic 		else if (x == zero)	/* NOT REACHED IF _IEEE */
36056955Sbostic 			return (infnan(-ERANGE));
36156955Sbostic 		else
36256955Sbostic 			return (infnan(EDOM));
36356955Sbostic 	else if (!finite(x))
36456955Sbostic 		if (_IEEE)		/* x = NaN, Inf */
36556955Sbostic 			return (x+x);
36656955Sbostic 		else
36756955Sbostic 			return (infnan(ERANGE));
36856955Sbostic 
36956955Sbostic 	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
37056955Sbostic 	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
37135679Sbostic 
37256955Sbostic 	m = logb(x);
37356955Sbostic 	g = ldexp(x, -m);
37456955Sbostic 	if (_IEEE && m == -1022) {
37556955Sbostic 		j = logb(g), m += j;
37656955Sbostic 		g = ldexp(g, -j);
37756955Sbostic 	}
37856955Sbostic 	j = N*(g-1) + .5;
37956955Sbostic 	F = (1.0/N) * j + 1;	/* F*128 is an integer in [128, 512] */
38056955Sbostic 	f = g - F;
38135679Sbostic 
38256955Sbostic 	/* Approximate expansion for log(1+f/F) ~= u + q */
38356955Sbostic 	g = 1/(2*F+f);
38456955Sbostic 	u = 2*f*g;
38556955Sbostic 	v = u*u;
38656955Sbostic 	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
38735679Sbostic 
38856955Sbostic     /* case 1: u1 = u rounded to 2^-43 absolute.  Since u < 2^-8,
38956955Sbostic      * 	       u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits.
39056955Sbostic      *         It also adds exactly to |m*log2_hi + log_F_head[j] | < 750
39156955Sbostic     */
39256955Sbostic 	if (m | j)
39356955Sbostic 		u1 = u + 513, u1 -= 513;
39424601Szliu 
39556955Sbostic     /* case 2:	|1-x| < 1/256. The m- and j- dependent terms are zero;
39656955Sbostic      * 		u1 = u to 24 bits.
39756955Sbostic     */
39856955Sbostic 	else
39956955Sbostic 		u1 = u, TRUNC(u1);
40056955Sbostic 	u2 = (2.0*(f - F*u1) - u1*f) * g;
40156955Sbostic 			/* u1 + u2 = 2f/(2F+f) to extra precision.	*/
40224601Szliu 
40356955Sbostic 	/* log(x) = log(2^m*F*(1+f/F)) =				*/
40456955Sbostic 	/* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q);	*/
40556955Sbostic 	/* (exact) + (tiny)						*/
40624601Szliu 
40756955Sbostic 	u1 += m*logF_head[N] + logF_head[j];		/* exact */
40856955Sbostic 	u2 = (u2 + logF_tail[j]) + q;			/* tiny */
40956955Sbostic 	u2 += logF_tail[N]*m;
41056955Sbostic 	return (u1 + u2);
41156955Sbostic }
41224601Szliu 
41357442Sbostic /*
41457442Sbostic  * Extra precision variant, returning struct {double a, b;};
41557442Sbostic  * log(x) = a+b to 63 bits, with a is rounded to 26 bits.
41656955Sbostic  */
41756955Sbostic struct Double
41856955Sbostic #ifdef _ANSI_SOURCE
__log__D(double x)41957452Sbostic __log__D(double x)
42056955Sbostic #else
42157452Sbostic __log__D(x) double x;
42256955Sbostic #endif
42356955Sbostic {
42456955Sbostic 	int m, j;
42557442Sbostic 	double F, f, g, q, u, v, u2, one = 1.0;
42656955Sbostic 	volatile double u1;
42756955Sbostic 	struct Double r;
42824601Szliu 
42956955Sbostic 	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
43056955Sbostic 	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
43124601Szliu 
43256955Sbostic 	m = logb(x);
43356955Sbostic 	g = ldexp(x, -m);
43456955Sbostic 	if (_IEEE && m == -1022) {
43556955Sbostic 		j = logb(g), m += j;
43656955Sbostic 		g = ldexp(g, -j);
43724601Szliu 	}
43856955Sbostic 	j = N*(g-1) + .5;
43956955Sbostic 	F = (1.0/N) * j + 1;
44056955Sbostic 	f = g - F;
44124601Szliu 
44256955Sbostic 	g = 1/(2*F+f);
44356955Sbostic 	u = 2*f*g;
44456955Sbostic 	v = u*u;
44556955Sbostic 	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
44656955Sbostic 	if (m | j)
44756955Sbostic 		u1 = u + 513, u1 -= 513;
44856955Sbostic 	else
44956955Sbostic 		u1 = u, TRUNC(u1);
45056955Sbostic 	u2 = (2.0*(f - F*u1) - u1*f) * g;
45124601Szliu 
45256955Sbostic 	u1 += m*logF_head[N] + logF_head[j];
45324601Szliu 
45456955Sbostic 	u2 +=  logF_tail[j]; u2 += q;
45556955Sbostic 	u2 += logF_tail[N]*m;
45656955Sbostic 	r.a = u1 + u2;			/* Only difference is here */
45756955Sbostic 	TRUNC(r.a);
45856955Sbostic 	r.b = (u1 - r.a) + u2;
45956955Sbostic 	return (r);
46024601Szliu }
461