xref: /titanic_51/usr/src/lib/libm/common/R/logf.c (revision ddc0e0b53c661f6e439e3b7072b3ef353eadb4af)
125c28e83SPiotr Jasiukajtis /*
225c28e83SPiotr Jasiukajtis  * CDDL HEADER START
325c28e83SPiotr Jasiukajtis  *
425c28e83SPiotr Jasiukajtis  * The contents of this file are subject to the terms of the
525c28e83SPiotr Jasiukajtis  * Common Development and Distribution License (the "License").
625c28e83SPiotr Jasiukajtis  * You may not use this file except in compliance with the License.
725c28e83SPiotr Jasiukajtis  *
825c28e83SPiotr Jasiukajtis  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
925c28e83SPiotr Jasiukajtis  * or http://www.opensolaris.org/os/licensing.
1025c28e83SPiotr Jasiukajtis  * See the License for the specific language governing permissions
1125c28e83SPiotr Jasiukajtis  * and limitations under the License.
1225c28e83SPiotr Jasiukajtis  *
1325c28e83SPiotr Jasiukajtis  * When distributing Covered Code, include this CDDL HEADER in each
1425c28e83SPiotr Jasiukajtis  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1525c28e83SPiotr Jasiukajtis  * If applicable, add the following below this CDDL HEADER, with the
1625c28e83SPiotr Jasiukajtis  * fields enclosed by brackets "[]" replaced with your own identifying
1725c28e83SPiotr Jasiukajtis  * information: Portions Copyright [yyyy] [name of copyright owner]
1825c28e83SPiotr Jasiukajtis  *
1925c28e83SPiotr Jasiukajtis  * CDDL HEADER END
2025c28e83SPiotr Jasiukajtis  */
2125c28e83SPiotr Jasiukajtis /*
2225c28e83SPiotr Jasiukajtis  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
2325c28e83SPiotr Jasiukajtis  */
2425c28e83SPiotr Jasiukajtis /*
2525c28e83SPiotr Jasiukajtis  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
2625c28e83SPiotr Jasiukajtis  * Use is subject to license terms.
2725c28e83SPiotr Jasiukajtis  */
2825c28e83SPiotr Jasiukajtis 
29*ddc0e0b5SRichard Lowe #pragma weak __logf = logf
3025c28e83SPiotr Jasiukajtis 
3125c28e83SPiotr Jasiukajtis /*
3225c28e83SPiotr Jasiukajtis  * Algorithm:
3325c28e83SPiotr Jasiukajtis  *
3425c28e83SPiotr Jasiukajtis  * Let y = x rounded to six significant bits.  Then for any choice
3525c28e83SPiotr Jasiukajtis  * of e and z such that y = 2^e z, we have
3625c28e83SPiotr Jasiukajtis  *
3725c28e83SPiotr Jasiukajtis  * log(x) = e log(2) + log(z) + log(1+(x-y)/y)
3825c28e83SPiotr Jasiukajtis  *
3925c28e83SPiotr Jasiukajtis  * Note that (x-y)/y = (x'-y')/y' for any scaled x' = sx, y' = sy;
4025c28e83SPiotr Jasiukajtis  * in particular, we can take s to be the power of two that makes
4125c28e83SPiotr Jasiukajtis  * ulp(x') = 1.
4225c28e83SPiotr Jasiukajtis  *
4325c28e83SPiotr Jasiukajtis  * From a table, obtain l = log(z) and r = 1/y'.  For |s| <= 2^-6,
4425c28e83SPiotr Jasiukajtis  * approximate log(1+s) by a polynomial p(s) where p(s) := s+s*s*
4525c28e83SPiotr Jasiukajtis  * (K1+s*(K2+s*K3)).  Then we compute the expression above as
4625c28e83SPiotr Jasiukajtis  * e*ln2 + l + p(r*(x'-y')) all evaluated in double precision.
4725c28e83SPiotr Jasiukajtis  *
4825c28e83SPiotr Jasiukajtis  * When x is subnormal, we first scale it to the normal range,
4925c28e83SPiotr Jasiukajtis  * adjusting e accordingly.
5025c28e83SPiotr Jasiukajtis  *
5125c28e83SPiotr Jasiukajtis  * Accuracy:
5225c28e83SPiotr Jasiukajtis  *
5325c28e83SPiotr Jasiukajtis  * The largest error is less than 0.6 ulps.
5425c28e83SPiotr Jasiukajtis  */
5525c28e83SPiotr Jasiukajtis 
5625c28e83SPiotr Jasiukajtis #include "libm.h"
5725c28e83SPiotr Jasiukajtis 
5825c28e83SPiotr Jasiukajtis /*
5925c28e83SPiotr Jasiukajtis  * For i = 0, ..., 12,
6025c28e83SPiotr Jasiukajtis  *   TBL[2i] = log(1 + i/32) and TBL[2i+1] = 2^-23 / (1 + i/32)
6125c28e83SPiotr Jasiukajtis  *
6225c28e83SPiotr Jasiukajtis  * For i = 13, ..., 32,
6325c28e83SPiotr Jasiukajtis  *   TBL[2i] = log(1/2 + i/64) and TBL[2i+1] = 2^-23 / (1 + i/32)
6425c28e83SPiotr Jasiukajtis  */
6525c28e83SPiotr Jasiukajtis static const double TBL[] = {
6625c28e83SPiotr Jasiukajtis 	0.000000000000000000e+00, 1.192092895507812500e-07,
6725c28e83SPiotr Jasiukajtis 	3.077165866675368733e-02, 1.155968868371212153e-07,
6825c28e83SPiotr Jasiukajtis 	6.062462181643483994e-02, 1.121969784007352926e-07,
6925c28e83SPiotr Jasiukajtis 	8.961215868968713805e-02, 1.089913504464285680e-07,
7025c28e83SPiotr Jasiukajtis 	1.177830356563834557e-01, 1.059638129340277719e-07,
7125c28e83SPiotr Jasiukajtis 	1.451820098444978890e-01, 1.030999260979729787e-07,
7225c28e83SPiotr Jasiukajtis 	1.718502569266592284e-01, 1.003867701480263102e-07,
7325c28e83SPiotr Jasiukajtis 	1.978257433299198675e-01, 9.781275040064102225e-08,
7425c28e83SPiotr Jasiukajtis 	2.231435513142097649e-01, 9.536743164062500529e-08,
7525c28e83SPiotr Jasiukajtis 	2.478361639045812692e-01, 9.304139672256097884e-08,
7625c28e83SPiotr Jasiukajtis 	2.719337154836417580e-01, 9.082612537202380448e-08,
7725c28e83SPiotr Jasiukajtis 	2.954642128938358980e-01, 8.871388989825581272e-08,
7825c28e83SPiotr Jasiukajtis 	3.184537311185345887e-01, 8.669766512784091150e-08,
7925c28e83SPiotr Jasiukajtis 	-3.522205935893520934e-01, 8.477105034722222546e-08,
8025c28e83SPiotr Jasiukajtis 	-3.302416868705768671e-01, 8.292820142663043248e-08,
8125c28e83SPiotr Jasiukajtis 	-3.087354816496132859e-01, 8.116377160904255122e-08,
8225c28e83SPiotr Jasiukajtis 	-2.876820724517809014e-01, 7.947285970052082892e-08,
8325c28e83SPiotr Jasiukajtis 	-2.670627852490452536e-01, 7.785096460459183052e-08,
8425c28e83SPiotr Jasiukajtis 	-2.468600779315257843e-01, 7.629394531250000159e-08,
8525c28e83SPiotr Jasiukajtis 	-2.270574506353460753e-01, 7.479798560049019504e-08,
8625c28e83SPiotr Jasiukajtis 	-2.076393647782444896e-01, 7.335956280048077330e-08,
8725c28e83SPiotr Jasiukajtis 	-1.885911698075500298e-01, 7.197542010613207272e-08,
8825c28e83SPiotr Jasiukajtis 	-1.698990367953974734e-01, 7.064254195601851460e-08,
8925c28e83SPiotr Jasiukajtis 	-1.515498981272009327e-01, 6.935813210227272390e-08,
9025c28e83SPiotr Jasiukajtis 	-1.335313926245226268e-01, 6.811959402901785336e-08,
9125c28e83SPiotr Jasiukajtis 	-1.158318155251217008e-01, 6.692451343201754014e-08,
9225c28e83SPiotr Jasiukajtis 	-9.844007281325252434e-02, 6.577064251077586116e-08,
9325c28e83SPiotr Jasiukajtis 	-8.134563945395240081e-02, 6.465588585805084723e-08,
9425c28e83SPiotr Jasiukajtis 	-6.453852113757117814e-02, 6.357828776041666578e-08,
9525c28e83SPiotr Jasiukajtis 	-4.800921918636060631e-02, 6.253602074795082293e-08,
9625c28e83SPiotr Jasiukajtis 	-3.174869831458029812e-02, 6.152737525201612732e-08,
9725c28e83SPiotr Jasiukajtis 	-1.574835696813916761e-02, 6.055075024801586965e-08,
9825c28e83SPiotr Jasiukajtis 	0.000000000000000000e+00, 5.960464477539062500e-08,
9925c28e83SPiotr Jasiukajtis };
10025c28e83SPiotr Jasiukajtis 
10125c28e83SPiotr Jasiukajtis static const double C[] = {
10225c28e83SPiotr Jasiukajtis 	6.931471805599452862e-01,
10325c28e83SPiotr Jasiukajtis 	-2.49887584306188944706e-01,
10425c28e83SPiotr Jasiukajtis 	3.33368809981254554946e-01,
10525c28e83SPiotr Jasiukajtis 	-5.00000008402474976565e-01
10625c28e83SPiotr Jasiukajtis };
10725c28e83SPiotr Jasiukajtis 
10825c28e83SPiotr Jasiukajtis #define	ln2	C[0]
10925c28e83SPiotr Jasiukajtis #define	K3	C[1]
11025c28e83SPiotr Jasiukajtis #define	K2	C[2]
11125c28e83SPiotr Jasiukajtis #define	K1	C[3]
11225c28e83SPiotr Jasiukajtis 
11325c28e83SPiotr Jasiukajtis float
11425c28e83SPiotr Jasiukajtis logf(float x)
11525c28e83SPiotr Jasiukajtis {
11625c28e83SPiotr Jasiukajtis 	double	v, t;
11725c28e83SPiotr Jasiukajtis 	float	f;
11825c28e83SPiotr Jasiukajtis 	int	hx, ix, i, exp, iy;
11925c28e83SPiotr Jasiukajtis 
12025c28e83SPiotr Jasiukajtis 	hx = *(int *)&x;
12125c28e83SPiotr Jasiukajtis 	ix = hx & ~0x80000000;
12225c28e83SPiotr Jasiukajtis 
12325c28e83SPiotr Jasiukajtis 	if (ix >= 0x7f800000)	/* nan or inf */
12425c28e83SPiotr Jasiukajtis 		return ((hx < 0)? x * 0.0f : x * x);
12525c28e83SPiotr Jasiukajtis 
12625c28e83SPiotr Jasiukajtis 	exp = 0;
12725c28e83SPiotr Jasiukajtis 	if (hx < 0x00800000) { /* negative, zero, or subnormal */
12825c28e83SPiotr Jasiukajtis 		if (hx <= 0) {
12925c28e83SPiotr Jasiukajtis 			f = 0.0f;
13025c28e83SPiotr Jasiukajtis 			return ((ix == 0)? -1.0f / f : f / f);
13125c28e83SPiotr Jasiukajtis 		}
13225c28e83SPiotr Jasiukajtis 
13325c28e83SPiotr Jasiukajtis 		/* subnormal; scale by 2^149 */
13425c28e83SPiotr Jasiukajtis 		f = (float)ix;
13525c28e83SPiotr Jasiukajtis 		ix = *(int *)&f;
13625c28e83SPiotr Jasiukajtis 		exp = -149;
13725c28e83SPiotr Jasiukajtis 	}
13825c28e83SPiotr Jasiukajtis 
13925c28e83SPiotr Jasiukajtis 	exp += (ix - 0x3f320000) >> 23;
14025c28e83SPiotr Jasiukajtis 	ix &= 0x007fffff;
14125c28e83SPiotr Jasiukajtis 	iy = (ix + 0x20000) & 0xfffc0000;
14225c28e83SPiotr Jasiukajtis 	i = iy >> 17;
14325c28e83SPiotr Jasiukajtis 	t = ln2 * (double)exp + TBL[i];
14425c28e83SPiotr Jasiukajtis 	v = (double)(ix - iy) * TBL[i + 1];
14525c28e83SPiotr Jasiukajtis 	v += (v * v) * (K1 + v * (K2 + v * K3));
14625c28e83SPiotr Jasiukajtis 	f = (float)(t + v);
14725c28e83SPiotr Jasiukajtis 	return (f);
14825c28e83SPiotr Jasiukajtis }
149