FastLED 3.9.15
Loading...
Searching...
No Matches
s16x16.h
Go to the documentation of this file.
1#pragma once
2
3// Signed 16.16 fixed-point arithmetic and trigonometry.
4// All operations are integer-only in the hot path.
5
6#include "fl/stl/stdint.h"
7#include "fl/math/sin32.h"
11#include "fl/stl/noexcept.h"
12#include "fl/stl/undef.h" // Undefine abs/min/max macros from Arduino.h
13
15
16namespace fl {
17
18// Signed 16.16 fixed-point value type.
19class s16x16 {
20 public:
21 static constexpr int INT_BITS = 16;
22 static constexpr int FRAC_BITS = 16;
23 static constexpr i32 SCALE = static_cast<i32>(1) << FRAC_BITS;
24
25 // ---- Construction ------------------------------------------------------
26
27 constexpr s16x16() FL_NOEXCEPT = default;
28
29 explicit constexpr s16x16(float f) FL_NOEXCEPT
30 : mValue(static_cast<i32>(f * (SCALE))) {}
31
32 // Integer constructor — any integer width (portable: AVR 16-bit int, ARM/x86 32-bit).
33 // Compile error if constexpr value exceeds INT_BITS range.
34 template <typename IntT, detail::enable_if_integer_t<IntT> = 0>
37
38 // Auto-promotion from other fixed-point types
39 // Enabled only when both INT_BITS and FRAC_BITS can be promoted (no demotion)
40 template <typename OtherFP>
41 constexpr s16x16(const OtherFP& other,
42 typename fl::enable_if<
43 (OtherFP::INT_BITS <= INT_BITS) &&
44 (OtherFP::FRAC_BITS <= FRAC_BITS) &&
45 (OtherFP::INT_BITS != INT_BITS || OtherFP::FRAC_BITS != FRAC_BITS),
46 int>::type = 0)
47 FL_NOEXCEPT : mValue(static_cast<i32>(
48 static_cast<i64>(other.raw()) << (FRAC_BITS - OtherFP::FRAC_BITS))) {}
49
50 // Raw constructor for C++11 constexpr from_raw
51 struct RawTag {};
52 constexpr explicit s16x16(i32 raw, RawTag) FL_NOEXCEPT : mValue(raw) {}
53
55 return s16x16(raw, RawTag());
56 }
57
58 // ---- Access ------------------------------------------------------------
59
60 constexpr i32 raw() const FL_NOEXCEPT { return mValue; }
61 constexpr i32 to_int() const FL_NOEXCEPT { return mValue >> FRAC_BITS; }
62 constexpr float to_float() const FL_NOEXCEPT { return static_cast<float>(mValue) / (SCALE); }
63
64 // ---- Fixed-point arithmetic --------------------------------------------
65
66#if defined(__riscv) && (__riscv_xlen == 32)
67 // RV32: Use mul+mulh inline asm to avoid expensive 64-bit widening multiply.
68 // Extracts bits [47:16] of the 64-bit product for Q16.16 fixed-point.
70 i32 lo, hi;
71 asm("mul %0, %2, %3\n\t"
72 "mulh %1, %2, %3"
73 : "=&r"(lo), "=&r"(hi)
74 : "r"(mValue), "r"(b.mValue));
75 return from_raw(static_cast<i32>(
76 (static_cast<u32>(lo) >> 16) | (static_cast<u32>(hi) << 16)));
77 }
78#else
80 return from_raw(static_cast<i32>(
81 (static_cast<i64>(mValue) * b.mValue) >> FRAC_BITS));
82 }
83#endif
84
86 return from_raw(static_cast<i32>(
87 (static_cast<i64>(mValue) * (static_cast<i64>(SCALE))) / b.mValue));
88 }
89
91 return from_raw(static_cast<i32>(
92 static_cast<u32>(mValue) + static_cast<u32>(b.mValue)));
93 }
94
96 return from_raw(static_cast<i32>(
97 static_cast<u32>(mValue) - static_cast<u32>(b.mValue)));
98 }
99
101 return from_raw(static_cast<i32>(0u - static_cast<u32>(mValue)));
102 }
103
105 return from_raw(mValue >> shift);
106 }
107
108 // ---- Scalar multiply (no fixed-point shift) ----------------------------
109
110 constexpr FASTLED_FORCE_INLINE s16x16 operator*(i32 scalar) const FL_NOEXCEPT {
111 return from_raw(mValue * scalar);
112 }
113
114 friend constexpr s16x16 operator*(i32 scalar, s16x16 fp) FL_NOEXCEPT {
115 return s16x16::from_raw(scalar * fp.mValue);
116 }
117
118 // ---- Comparisons -------------------------------------------------------
119
120 constexpr bool operator<(s16x16 b) const FL_NOEXCEPT { return mValue < b.mValue; }
121 constexpr bool operator>(s16x16 b) const FL_NOEXCEPT { return mValue > b.mValue; }
122 constexpr bool operator<=(s16x16 b) const FL_NOEXCEPT { return mValue <= b.mValue; }
123 constexpr bool operator>=(s16x16 b) const FL_NOEXCEPT { return mValue >= b.mValue; }
124 constexpr bool operator==(s16x16 b) const FL_NOEXCEPT { return mValue == b.mValue; }
125 constexpr bool operator!=(s16x16 b) const FL_NOEXCEPT { return mValue != b.mValue; }
126
127 // ---- Math ---------------------------------------------------------------
128
130 return from_raw(a.mValue % b.mValue);
131 }
132
134 return from_raw(x.mValue & ~(i32((SCALE) - 1)));
135 }
136
138 return from_raw((x.mValue & ~(i32((SCALE) - 1))) +
139 ((x.mValue & i32((SCALE) - 1)) ? (SCALE) : 0));
140 }
141
143 return from_raw(x.mValue & i32((SCALE) - 1));
144 }
145
147 return from_raw(x.mValue < 0 ? -x.mValue : x.mValue);
148 }
149
151 return x.mValue > 0 ? 1 : (x.mValue < 0 ? -1 : 0);
152 }
153
154#if defined(__riscv) && (__riscv_xlen == 32)
156#else
158#endif
159 return a + (b - a) * t;
160 }
161
163 return x < lo ? lo : (x > hi ? hi : x);
164 }
165
167 return x < edge ? s16x16() : s16x16(1.0f);
168 }
169
171 constexpr s16x16 zero(0.0f);
172 constexpr s16x16 one(1.0f);
173 constexpr s16x16 two(2.0f);
174 constexpr s16x16 three(3.0f);
175 s16x16 t = clamp((x - edge0) / (edge1 - edge0), zero, one);
176 return t * t * (three - two * t);
177 }
178
179 // ---- Inverse Trigonometry (pure fixed-point) ----------------------------
180
182 constexpr s16x16 one(1.0f);
183 constexpr s16x16 pi_over_2(1.5707963f);
184 bool neg = x.mValue < 0;
185 s16x16 ax = abs(x);
187 if (ax <= one) {
188 result = atan_unit(ax);
189 } else {
190 result = pi_over_2 - atan_unit(one / ax);
191 }
192 return neg ? -result : result;
193 }
194
196 constexpr s16x16 pi(3.1415926f);
197 constexpr s16x16 pi_over_2(1.5707963f);
198 if (x.mValue == 0 && y.mValue == 0) return s16x16();
199 if (x.mValue == 0) return y.mValue > 0 ? pi_over_2 : -pi_over_2;
200 if (y.mValue == 0) return x.mValue > 0 ? s16x16() : pi;
201 s16x16 ax = abs(x);
202 s16x16 ay = abs(y);
203 s16x16 a;
204 if (ax >= ay) {
205 a = atan_unit(ay / ax);
206 } else {
207 a = pi_over_2 - atan_unit(ax / ay);
208 }
209 if (x.mValue < 0) a = pi - a;
210 if (y.mValue < 0) a = -a;
211 return a;
212 }
213
215 constexpr s16x16 one(1.0f);
216 return atan2(x, sqrt(one - x * x));
217 }
218
220 constexpr s16x16 one(1.0f);
221 return atan2(sqrt(one - x * x), x);
222 }
223
225 return x.mValue <= 0 ? s16x16() : from_raw(static_cast<i32>(
226 fl::isqrt64(static_cast<u64>(x.mValue) << FRAC_BITS)));
227 }
228
230 return sqrt(x).mValue == 0
231 ? s16x16()
232 : from_raw(SCALE) / sqrt(x);
233 }
234
236 if (base.mValue <= 0) return s16x16();
237 constexpr s16x16 one(1.0f);
238 if (exp.mValue == 0) return one;
239 if (base == one) return one;
240 // Snap base values within ~2 ULPs of 1.0 to exactly 1.0 to dodge the
241 // log2(1+t) minimax polynomial's upper-endpoint residual (#2969).
242 constexpr i32 kOneRaw = static_cast<i32>(SCALE);
243 if (base.mValue >= (kOneRaw - 2) && base.mValue <= kOneRaw) {
244 return one;
245 }
246 return exp2_fp(exp * log2_fp(base));
247 }
248
249 // ---- Member function versions (operate on *this) -----------------------
250
252 return floor(*this);
253 }
254
256 return ceil(*this);
257 }
258
260 return fract(*this);
261 }
262
264 return abs(*this);
265 }
266
267 constexpr FASTLED_FORCE_INLINE int sign() const FL_NOEXCEPT {
268 return sign(*this);
269 }
270
272 return sin(*this);
273 }
274
276 return cos(*this);
277 }
278
280 return atan(*this);
281 }
282
284 return asin(*this);
285 }
286
288 return acos(*this);
289 }
290
292 return sqrt(*this);
293 }
294
296 return rsqrt(*this);
297 }
298
299 // ---- Trigonometry ------------------------------------------------------
300
302 return from_raw(fl::sin32(angle_to_a24(angle)) >> 15);
303 }
304
306 return from_raw(fl::cos32(angle_to_a24(angle)) >> 15);
307 }
308
309 // Combined sin+cos from s16x16 radians. Output in s16x16 [-1, 1].
310 // Uses sincos32 which shares angle decomposition for ~30% fewer ops.
311 static FASTLED_FORCE_INLINE void sincos(s16x16 angle, s16x16 &out_sin,
312 s16x16 &out_cos) FL_NOEXCEPT {
313 u32 a24 = angle_to_a24(angle);
314 fl::SinCos32 sc = fl::sincos32(a24);
315 out_sin = from_raw(sc.sin_val >> 15);
316 out_cos = from_raw(sc.cos_val >> 15);
317 }
318
319 private:
320 i32 mValue = 0;
321
322 // Returns 0-based position of highest set bit, or -1 if v==0.
323 static constexpr FASTLED_FORCE_INLINE int highest_bit(u32 v) FL_NOEXCEPT {
324 return v == 0 ? -1 : _highest_bit_step(v, 0);
325 }
326
327 static constexpr int _highest_bit_step(u32 v, int r) FL_NOEXCEPT {
328 return (v & 0xFFFF0000u) ? _highest_bit_step(v >> 16, r + 16)
329 : (v & 0x0000FF00u) ? _highest_bit_step(v >> 8, r + 8)
330 : (v & 0x000000F0u) ? _highest_bit_step(v >> 4, r + 4)
331 : (v & 0x0000000Cu) ? _highest_bit_step(v >> 2, r + 2)
332 : (v & 0x00000002u) ? r + 1
333 : r;
334 }
335
336 // Fixed-point log base 2 for positive values.
337 // Uses 4-term minimax polynomial for log2(1+t), t in [0,1).
338 // Horner evaluation uses i64 intermediates (24 frac bits) to minimize
339 // rounding error, then converts back to 16 frac bits.
341 u32 val = static_cast<u32>(x.mValue);
342 int msb = highest_bit(val);
343 i32 int_part = msb - FRAC_BITS;
344 i32 t;
345 if (msb >= FRAC_BITS) {
346 t = static_cast<i32>(
347 (val >> (msb - FRAC_BITS)) - (SCALE));
348 } else {
349 t = static_cast<i32>(
350 (val << (FRAC_BITS - msb)) - (SCALE));
351 }
352 // 4-term minimax coefficients for log2(1+t), t in [0,1).
353 // Stored as i64 with 24 fractional bits. Max product ~2^49, fits i64.
354 constexpr int IFRAC = 24;
355 constexpr i64 c0 = 24189248LL; // 1.44179 * 2^24
356 constexpr i64 c1 = -11728384LL; // -0.69907 * 2^24
357 constexpr i64 c2 = 6098176LL; // 0.36348 * 2^24
358 constexpr i64 c3 = -1788416LL; // -0.10660 * 2^24
359 // Extend t from 16 to 24 frac bits.
360 i64 t24 = static_cast<i64>(t) << (IFRAC - FRAC_BITS);
361 // Horner: t * (c0 + t * (c1 + t * (c2 + t * c3)))
362 i64 acc = c3;
363 acc = c2 + ((acc * t24) >> IFRAC);
364 acc = c1 + ((acc * t24) >> IFRAC);
365 acc = c0 + ((acc * t24) >> IFRAC);
366 i64 frac_part = (acc * t24) >> IFRAC;
367 // Convert from 24 frac bits back to 16.
368 i32 frac16 = static_cast<i32>(frac_part >> (IFRAC - FRAC_BITS));
369 return from_raw(static_cast<i32>(static_cast<u32>(int_part) << FRAC_BITS) + frac16);
370 }
371
372 // Fixed-point 2^x. Uses 4-term minimax polynomial for 2^t, t in [0,1).
373 // Horner evaluation uses i64 intermediates (24 frac bits) to minimize
374 // rounding error, then converts back to 16 frac bits.
376 s16x16 fl_val = floor(x);
377 s16x16 fr = x - fl_val;
378 i32 n = fl_val.mValue >> FRAC_BITS;
379 if (n >= INT_BITS - 1) return from_raw(0x7FFFFFFF);
380 if (n < -FRAC_BITS) return s16x16();
381 i32 int_pow;
382 if (n >= 0) {
383 int_pow = static_cast<i32>(SCALE) << n;
384 } else {
385 int_pow = static_cast<i32>(SCALE) >> (-n);
386 }
387 // 4-term minimax coefficients for 2^t - 1, t in [0,1).
388 // Stored as i64 with 24 fractional bits. Max product ~2^48, fits i64.
389 constexpr int IFRAC = 24;
390 constexpr i64 d0 = 11629376LL; // 0.69316 * 2^24
391 constexpr i64 d1 = 4038400LL; // 0.24071 * 2^24
392 constexpr i64 d2 = 895232LL; // 0.05336 * 2^24
393 constexpr i64 d3 = 214016LL; // 0.01276 * 2^24
394 // Extend fr from 16 to 24 frac bits.
395 i64 fr24 = static_cast<i64>(fr.mValue) << (IFRAC - FRAC_BITS);
396 // Horner: 1 + fr * (d0 + fr * (d1 + fr * (d2 + fr * d3)))
397 i64 acc = d3;
398 acc = d2 + ((acc * fr24) >> IFRAC);
399 acc = d1 + ((acc * fr24) >> IFRAC);
400 acc = d0 + ((acc * fr24) >> IFRAC);
401 constexpr i64 one24 = 1LL << IFRAC;
402 i64 frac_pow24 = one24 + ((acc * fr24) >> IFRAC);
403 // Convert from 24 frac bits to 16 frac bits, then scale by int_pow.
404 i32 frac_pow16 = static_cast<i32>(frac_pow24 >> (IFRAC - FRAC_BITS));
405 i64 result =
406 (static_cast<i64>(int_pow) * frac_pow16) >> FRAC_BITS;
407 return from_raw(static_cast<i32>(result));
408 }
409
410 // Converts s16x16 radians to sin32/cos32 input format.
411 // 256/(2*PI) — converts radians to sin32/cos32 format.
412 static constexpr i32 RAD_TO_24 = 2670177;
414 return static_cast<u32>(
415 (static_cast<i64>(angle.mValue) * RAD_TO_24) >> FRAC_BITS);
416 }
417
418 // Polynomial atan for t in [0, 1]. Returns [0, π/4].
419 // 7th-order minimax: atan(t) ≈ t * (c0 + t² * (c1 + t² * (c2 + t² * c3)))
420 // Coefficients optimized via coordinate descent on s16x16 quantization grid.
422 constexpr s16x16 c0(0.9998779297f);
423 constexpr s16x16 c1(-0.3269348145f);
424 constexpr s16x16 c2(0.1594085693f);
425 constexpr s16x16 c3(-0.0472106934f);
426 s16x16 t2 = t * t;
427 return t * (c0 + t2 * (c1 + t2 * (c2 + t2 * c3)));
428 }
429};
430
431} // namespace fl
432
static constexpr FASTLED_FORCE_INLINE s16x16 sqrt(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:224
static FASTLED_FORCE_INLINE s16x16 log2_fp(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:340
static constexpr FASTLED_FORCE_INLINE int highest_bit(u32 v) FL_NOEXCEPT
Definition s16x16.h:323
constexpr float to_float() const FL_NOEXCEPT
Definition s16x16.h:62
constexpr FASTLED_FORCE_INLINE s16x16 ceil() const FL_NOEXCEPT
Definition s16x16.h:255
static constexpr i32 SCALE
Definition s16x16.h:23
static FASTLED_FORCE_INLINE void sincos(s16x16 angle, s16x16 &out_sin, s16x16 &out_cos) FL_NOEXCEPT
Definition s16x16.h:311
static constexpr FASTLED_FORCE_INLINE s16x16 mod(s16x16 a, s16x16 b) FL_NOEXCEPT
Definition s16x16.h:129
constexpr FASTLED_FORCE_INLINE int sign() const FL_NOEXCEPT
Definition s16x16.h:267
static constexpr FASTLED_FORCE_INLINE s16x16 clamp(s16x16 x, s16x16 lo, s16x16 hi) FL_NOEXCEPT
Definition s16x16.h:162
static constexpr FASTLED_FORCE_INLINE s16x16 ceil(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:137
constexpr s16x16(IntT n) FL_NOEXCEPT
Definition s16x16.h:35
constexpr FASTLED_FORCE_INLINE s16x16 floor() const FL_NOEXCEPT
Definition s16x16.h:251
constexpr FASTLED_FORCE_INLINE s16x16 operator/(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:85
static FASTLED_FORCE_INLINE s16x16 atan(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:181
constexpr FASTLED_FORCE_INLINE s16x16 rsqrt() const FL_NOEXCEPT
Definition s16x16.h:295
static constexpr int INT_BITS
Definition s16x16.h:21
static FASTLED_FORCE_INLINE s16x16 sin(s16x16 angle) FL_NOEXCEPT
Definition s16x16.h:301
constexpr bool operator!=(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:125
static FASTLED_FORCE_INLINE s16x16 asin(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:214
constexpr FASTLED_FORCE_INLINE s16x16 sqrt() const FL_NOEXCEPT
Definition s16x16.h:291
constexpr i32 to_int() const FL_NOEXCEPT
Definition s16x16.h:61
static constexpr i32 RAD_TO_24
Definition s16x16.h:412
constexpr s16x16() FL_NOEXCEPT=default
constexpr FASTLED_FORCE_INLINE s16x16 fract() const FL_NOEXCEPT
Definition s16x16.h:259
FASTLED_FORCE_INLINE s16x16 cos() const FL_NOEXCEPT
Definition s16x16.h:275
static constexpr int FRAC_BITS
Definition s16x16.h:22
static FASTLED_FORCE_INLINE s16x16 exp2_fp(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:375
constexpr bool operator>(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:121
constexpr FASTLED_FORCE_INLINE s16x16 operator-() const FL_NOEXCEPT
Definition s16x16.h:100
constexpr bool operator>=(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:123
static constexpr FASTLED_FORCE_INLINE s16x16 fract(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:142
FASTLED_FORCE_INLINE s16x16 asin() const FL_NOEXCEPT
Definition s16x16.h:283
FASTLED_FORCE_INLINE s16x16 atan() const FL_NOEXCEPT
Definition s16x16.h:279
static constexpr FASTLED_FORCE_INLINE s16x16 floor(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:133
constexpr FASTLED_FORCE_INLINE s16x16 abs() const FL_NOEXCEPT
Definition s16x16.h:263
constexpr s16x16(i32 raw, RawTag) FL_NOEXCEPT
Definition s16x16.h:52
static constexpr FASTLED_FORCE_INLINE s16x16 from_raw(i32 raw) FL_NOEXCEPT
Definition s16x16.h:54
static FASTLED_FORCE_INLINE s16x16 smoothstep(s16x16 edge0, s16x16 edge1, s16x16 x) FL_NOEXCEPT
Definition s16x16.h:170
constexpr i32 raw() const FL_NOEXCEPT
Definition s16x16.h:60
static constexpr FASTLED_FORCE_INLINE s16x16 abs(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:146
i32 mValue
Definition s16x16.h:320
constexpr bool operator==(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:124
constexpr FASTLED_FORCE_INLINE s16x16 operator-(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:95
static FASTLED_FORCE_INLINE s16x16 cos(s16x16 angle) FL_NOEXCEPT
Definition s16x16.h:305
constexpr FASTLED_FORCE_INLINE s16x16 operator+(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:90
FASTLED_FORCE_INLINE s16x16 sin() const FL_NOEXCEPT
Definition s16x16.h:271
static constexpr FASTLED_FORCE_INLINE u32 angle_to_a24(s16x16 angle) FL_NOEXCEPT
Definition s16x16.h:413
constexpr bool operator<(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:120
FASTLED_FORCE_INLINE s16x16 acos() const FL_NOEXCEPT
Definition s16x16.h:287
constexpr FASTLED_FORCE_INLINE s16x16 operator>>(int shift) const FL_NOEXCEPT
Definition s16x16.h:104
static constexpr FASTLED_FORCE_INLINE int sign(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:150
static FASTLED_FORCE_INLINE s16x16 pow(s16x16 base, s16x16 exp) FL_NOEXCEPT
Definition s16x16.h:235
constexpr FASTLED_FORCE_INLINE s16x16 operator*(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:79
static constexpr int _highest_bit_step(u32 v, int r) FL_NOEXCEPT
Definition s16x16.h:327
static FASTLED_FORCE_INLINE s16x16 acos(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:219
constexpr s16x16(const OtherFP &other, typename fl::enable_if<(OtherFP::INT_BITS<=INT_BITS) &&(OtherFP::FRAC_BITS<=FRAC_BITS) &&(OtherFP::INT_BITS !=INT_BITS||OtherFP::FRAC_BITS !=FRAC_BITS), int >::type=0) FL_NOEXCEPT
Definition s16x16.h:41
static FASTLED_FORCE_INLINE s16x16 atan2(s16x16 y, s16x16 x) FL_NOEXCEPT
Definition s16x16.h:195
constexpr bool operator<=(s16x16 b) const FL_NOEXCEPT
Definition s16x16.h:122
static constexpr FASTLED_FORCE_INLINE s16x16 step(s16x16 edge, s16x16 x) FL_NOEXCEPT
Definition s16x16.h:166
constexpr FASTLED_FORCE_INLINE s16x16 operator*(i32 scalar) const FL_NOEXCEPT
Definition s16x16.h:110
static constexpr FASTLED_FORCE_INLINE s16x16 rsqrt(s16x16 x) FL_NOEXCEPT
Definition s16x16.h:229
friend constexpr s16x16 operator*(i32 scalar, s16x16 fp) FL_NOEXCEPT
Definition s16x16.h:114
static FASTLED_FORCE_INLINE s16x16 atan_unit(s16x16 t) FL_NOEXCEPT
Definition s16x16.h:421
static constexpr FASTLED_FORCE_INLINE s16x16 lerp(s16x16 a, s16x16 b, s16x16 t) FL_NOEXCEPT
Definition s16x16.h:157
#define constexpr
Declares that it is possible to evaluate a value at compile time, introduced in C++11.
Definition cpp_compat.h:15
FASTLED_FORCE_INLINE i32 cos32(u32 angle) FL_NOEXCEPT
Definition sin32.h:81
FASTLED_FORCE_INLINE i32 sin32(u32 angle) FL_NOEXCEPT
Definition sin32.h:59
fl::i64 i64
Definition s16x16x4.h:222
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
FASTLED_FORCE_INLINE SinCos32 sincos32(u32 angle) FL_NOEXCEPT
Definition sin32.h:88
fl::u64 u64
Definition s16x16x4.h:221
enable_if< is_fixed_point< T >::value, T >::type exp(T x) FL_NOEXCEPT
FL_OPTIMIZE_FUNCTION constexpr u32 isqrt64(u64 x) FL_NOEXCEPT
Definition isqrt.h:58
Base definition for an LED controller.
Definition crgb.hpp:179
i32 sin_val
Definition sin32.h:25
i32 cos_val
Definition sin32.h:26
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FASTLED_FORCE_INLINE
#define FL_OPTIMIZATION_LEVEL_O3_END
#define FL_NOEXCEPT