eerimoq / simba
1
/*
2
 * The MIT License (MIT)
3
 *
4
 * Copyright (c) 2015 Dan Moulding (logarithms)
5
 * Copyright (c) 2017-2018, Erik Moqvist
6
 *
7
 * Permission is hereby granted, free of charge, to any person
8
 * obtaining a copy of this software and associated documentation
9
 * files (the "Software"), to deal in the Software without
10
 * restriction, including without limitation the rights to use, copy,
11
 * modify, merge, publish, distribute, sublicense, and/or sell copies
12
 * of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be
16
 * included in all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 * This file is part of the Simba project.
28
 */
29

30
#include "simba.h"
31

32
/* Inverse log base 2 of e. */
33
#define INV_LOG2_E_Q1DOT31  UINT64_C(0x58b90bfc)
34

35
/* Inverse log base 2 of 10. */
36
#define INV_LOG2_10_Q1DOT31 UINT64_C(0x268826a1)
37

38
#if CONFIG_FLOAT == 1
39

40 1
float math_radians_to_degrees(float value)
41
{
42 1
    return (value * 180.0f / MATH_PI);
43
}
44

45 1
float math_degrees_to_radians(float value)
46
{
47 1
    return (value * MATH_PI / 180.0f);
48
}
49

50
#endif
51

52
/* This implementation is based on Clay. S. Turner's fast binary
53
   logarithm algorithm[1], and Dan Moulding's C implementation found
54
   here: https://github.com/dmoulding/log2fix. */
55 1
int32_t math_log2_fixed_point(uint32_t x, int precision)
56
{
57 1
    ASSERTN((precision > 0) && (precision < 32), EINVAL);
58

59
    int32_t b;
60
    int32_t y;
61
    uint64_t z;
62
    size_t i;
63

64 1
    b = (1 << (precision - 1));
65 1
    y = 0;
66

67 1
    if (x == 0) {
68 1
        return (INT32_MIN);
69
    }
70

71 1
    while (x < (1 << precision)) {
72 1
        x <<= 1;
73 1
        y -= (1 << precision);
74
    }
75

76 1
    while (x >= (2 << precision)) {
77 1
        x >>= 1;
78 1
        y += (1 << precision);
79
    }
80

81 1
    z = x;
82

83 1
    for (i = 0; i < precision; i++) {
84 1
        z = ((z * z) >> precision);
85

86 1
        if (z >= (2 << precision)) {
87 1
            z >>= 1;
88 1
            y += b;
89
        }
90

91 1
        b >>= 1;
92
    }
93

94 1
    return (y);
95
}
96

97 1
int32_t math_ln_fixed_point(uint32_t x, int precision)
98
{
99
    uint64_t y;
100

101 1
    y = math_log2_fixed_point(x, precision) * INV_LOG2_E_Q1DOT31;
102

103 1
    return (y >> 31);
104
}
105

106 1
int32_t math_log10_fixed_point(uint32_t x, int precision)
107
{
108
    uint64_t y;
109

110 1
    y = math_log2_fixed_point(x, precision) * INV_LOG2_10_Q1DOT31;
111

112 1
    return (y >> 31);
113
}

Read our documentation on viewing source code .

Loading