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