amath  1.8.5
Simple command line calculator
log10.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * Project homepage:
26  * https://amath.innolan.net
27  *
28  * The original source code can be obtained from:
29  * http://www.netlib.org/fdlibm/e_log10.c
30  *
31  * =================================================================
32  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
33  *
34  * Developed at SunSoft, a Sun Microsystems, Inc. business.
35  * Permission to use, copy, modify, and distribute this
36  * software is freely granted, provided that this notice
37  * is preserved.
38  * =================================================================
39  */
40 
41 /**
42  * @file log10.c
43  * @brief Base 10 logarithm function
44  */
45 
46 #include "prim.h"
47 
48 static const double
49 two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
50 ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */
51 log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
52 log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
53 
54 static double zero = 0.0;
55 
56 /**
57  * @brief Base 10 logarithm function
58  * @details
59  * <pre>
60  * Method:
61  *
62  * Let log10_2hi = leading 40 bits of log10(2) and
63  * log10_2lo = log10(2) - log10_2hi,
64  * ivln10 = 1/log(10) rounded.
65  * Then
66  * n = ilogb(x),
67  * if(n<0) n = n+1;
68  * x = scalbn(x,-n);
69  * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))
70  *
71  * Note 1:
72  * To guarantee log10(10**n)=n, where 10**n is normal, the rounding
73  * mode must set to Round-to-Nearest.
74  *
75  * Note 2:
76  * [1/log(10)] rounded to 53 bits has error .198 ulps;
77  * log10 is monotonic at all binary break points.
78  *
79  * Special cases:
80  *
81  * log10(x) is NaN with signal if x < 0;
82  * log10(+INF) is +INF with no signal; log10(0) is -INF with signal;
83  * log10(NaN) is that NaN with no signal;
84  * log10(10**N) = N for N=0,1,...,22.
85  *
86  * Constants:
87  * The hexadecimal values are the intended ones for the following constants.
88  * The decimal values may be used, provided that the compiler will convert
89  * from decimal to binary accurately enough to produce the hexadecimal values
90  * shown.
91  * </pre>
92  */
93 double log10(double x)
94 {
95  double y,z;
96  int32_t i,k,hx;
97  uint32_t lx;
98 
99  EXTRACT_WORDS(hx,lx,x);
100 
101  k=0;
102  if (hx < 0x00100000) { /* x < 2**-1022 */
103  if (((hx&0x7fffffff)|lx)==0)
104  return -two54/zero; /* log(+-0)=-inf */
105  if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
106  k -= 54;
107  x *= two54; /* subnormal number, scale up x */
108  GET_HIGH_WORD(hx, x); /* high word of x */
109  }
110  if (hx >= 0x7ff00000) return x+x;
111  k += (hx>>20)-1023;
112  i = ((uint32_t)k&0x80000000)>>31;
113  hx = (hx&0x000fffff)|((0x3ff-i)<<20);
114  y = (double)(k+i);
115  SET_HIGH_WORD(x,hx);
116  z = y*log10_2lo + ivln10*log(x);
117  return z+y*log10_2hi;
118 }
double log(double x)
Natural logarithm function (base e)
Definition: log.c:109
static double zero
Definition: log10.c:54
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
double log10(double x)
Base 10 logarithm function.
Definition: log10.c:93
#define EXTRACT_WORDS(ix0, ix1, d)
Get two 32 bit ints from a double.
Definition: prim.h:156
static const double two54
Definition: log10.c:49
static const double log10_2hi
Definition: log10.c:51
static const double ivln10
Definition: log10.c:50
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
static const double log10_2lo
Definition: log10.c:52