forked from parallella/pal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
p_ln.c
43 lines (37 loc) · 1.18 KB
/
p_ln.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <pal.h>
/**
*
* Calculates the natural logarithm of 'a', (where the base is 'e'=2.71828)
*
* @param a Pointer to input vector
*
* @param c Pointer to output vector
*
* @param n Size of 'a' and 'c' vector.
*
* @return None
*
*/
void p_ln_f32(const float *a, float *c, int n)
{
int i;
for (i = 0; i < n; i++) {
union
{
float f;
uint32_t i;
} u = { *(a + i) };
// Calculate the exponent (which is the floor of the logarithm) minus one
int e = ((u.i >> 23) & 0xff) - 0x80;
// Mask off the exponent, leaving just the mantissa
u.i = (u.i & 0x7fffff) + 0x3f800000;
// Interpolate using a cubic minimax polynomial derived with
// the Remez exchange algorithm. Coefficients courtesy of Alex Kan.
// This approximates 1 + log2 of the mantissa.
float r = ((0.15824870f * u.f - 1.05187502f) * u.f + 3.04788415f) * u.f - 1.15360271f;
// The log2 of the complete value is then the sum
// of the previous quantities (the 1's cancel), and
// we find the natural log by scaling by log2(e).
*(c + i) = (e + r) * M_LN2;
}
}