imath.h
1 /*
2  * SPDX-FileCopyrightText: 2023 ML!PA Consulting GmbH
3  * SPDX-License-Identifier: LGPL-2.1-only
4  */
5 
6 #pragma once
7 
20 #include <stdint.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #define SINI_PERIOD 0x8000
27 #define SINI_MAX 0x1000
28 #define SINI_MIN -0x1000
38 static inline __attribute__((always_inline))
39 int32_t _ihelp(int32_t x)
40 {
41  int32_t y;
42  static const int32_t qN = 13,
43  qA = 12,
44  B = 19900,
45  C = 3516;
46 
47  x = x << (31 - qN); /* Mask with PI */
48  x = x >> (31 - qN); /* Note: SIGNED shift! (to qN) */
49  x = x * x >> (2 * qN - 14); /* x=x^2 To Q14 */
50 
51  y = B - (x * C >> 14); /* B - x^2*C */
52  y = (1 << qA) /* A - x^2*(B-x^2*C) */
53  - (x * y >> 16);
54 
55  return y;
56 }
57 
65 static inline int32_t fast_sini(int32_t x)
66 {
67  static const int32_t qN = 13;
68 
69  int32_t c = x << (30 - qN);
70  int32_t y = _ihelp(x - (1 << qN));
71 
72  return c >= 0 ? y :-y;
73 }
74 
82 static inline int32_t fast_cosi(int32_t x)
83 {
84  static const int32_t qN = 13;
85 
86  int32_t c = (x + (SINI_PERIOD >> 2)) << (30 - qN);
87  int32_t y = _ihelp(x);
88 
89  return c >= 0 ? y :-y;
90 }
91 
98 static inline unsigned sqrti(unsigned x)
99 {
100  if (x <= 1) {
101  return x;
102  }
103 
104  /* initial estimate */
105  unsigned y0 = x >> 1;
106  unsigned y1 = (y0 + x / y0) >> 1;
107 
108  while (y1 < y0) {
109  y0 = y1;
110  y1 = (y0 + x / y0) >> 1;
111  }
112 
113  return y0;
114 }
115 
124 static inline uint32_t powi(unsigned x, unsigned y)
125 {
126  uint32_t res = 1;
127 
128  while (y--) {
129  res *= x;
130  }
131 
132  return res;
133 }
134 
135 #ifdef __cplusplus
136 }
137 #endif
138 
static int32_t fast_sini(int32_t x)
A sine approximation via a fourth-order cosine approx.
Definition: imath.h:65
static uint32_t powi(unsigned x, unsigned y)
Returns the value of x to the power of y.
Definition: imath.h:124
static unsigned sqrti(unsigned x)
Square root of an integer.
Definition: imath.h:98
static int32_t _ihelp(int32_t x)
Internal fast_sini/fast_cosi helper function.
Definition: imath.h:39
#define SINI_PERIOD
Period of the fast_sini() function.
Definition: imath.h:26
static int32_t fast_cosi(int32_t x)
A a fourth-order cosine approx.
Definition: imath.h:82