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