FastLED 3.9.15
Loading...
Searching...
No Matches
s4x12.h
Go to the documentation of this file.
1#pragma once
2
3// Signed 4.12 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 4.12 fixed-point value type.
19class s4x12 {
20 public:
21 static constexpr int INT_BITS = 4;
22 static constexpr int FRAC_BITS = 12;
23 static constexpr i32 SCALE = static_cast<i32>(1) << FRAC_BITS;
24
25 // ---- Construction ------------------------------------------------------
26
27 constexpr s4x12() FL_NOEXCEPT = default;
28
29 explicit constexpr s4x12(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 s4x12(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 s4x12(i16 raw, RawTag) FL_NOEXCEPT : mValue(raw) {}
52
54 return s4x12(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 s4x12 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 s4x12 operator*(i16 scalar) const FL_NOEXCEPT {
97 return from_raw(mValue * scalar);
98 }
99
100 friend constexpr s4x12 operator*(i16 scalar, s4x12 fp) FL_NOEXCEPT {
101 return s4x12::from_raw(scalar * fp.mValue);
102 }
103
104 // ---- Comparisons -------------------------------------------------------
105
106 constexpr bool operator<(s4x12 b) const FL_NOEXCEPT { return mValue < b.mValue; }
107 constexpr bool operator>(s4x12 b) const FL_NOEXCEPT { return mValue > b.mValue; }
108 constexpr bool operator<=(s4x12 b) const FL_NOEXCEPT { return mValue <= b.mValue; }
109 constexpr bool operator>=(s4x12 b) const FL_NOEXCEPT { return mValue >= b.mValue; }
110 constexpr bool operator==(s4x12 b) const FL_NOEXCEPT { return mValue == b.mValue; }
111 constexpr bool operator!=(s4x12 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 ? s4x12() : s4x12(1.0f);
150 }
151
153 constexpr s4x12 zero(0.0f);
154 constexpr s4x12 one(1.0f);
155 constexpr s4x12 two(2.0f);
156 constexpr s4x12 three(3.0f);
157 s4x12 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 s4x12 one(1.0f);
165 constexpr s4x12 pi_over_2(1.5707963f);
166 bool neg = x.mValue < 0;
167 s4x12 ax = abs(x);
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 s4x12 pi(3.1415926f);
179 constexpr s4x12 pi_over_2(1.5707963f);
180 if (x.mValue == 0 && y.mValue == 0) return s4x12();
181 if (x.mValue == 0) return y.mValue > 0 ? pi_over_2 : -pi_over_2;
182 if (y.mValue == 0) return x.mValue > 0 ? s4x12() : pi;
183 s4x12 ax = abs(x);
184 s4x12 ay = abs(y);
185 s4x12 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 s4x12 one(1.0f);
198 return atan2(x, sqrt(one - x * x));
199 }
200
202 constexpr s4x12 one(1.0f);
203 return atan2(sqrt(one - x * x), x);
204 }
205
207 return x.mValue <= 0 ? s4x12() : from_raw(static_cast<i16>(
208 fl::isqrt32(static_cast<u32>(x.mValue) << FRAC_BITS)));
209 }
210
212 return sqrt(x).mValue == 0
213 ? s4x12()
214 : from_raw(SCALE) / sqrt(x);
215 }
216
218 if (base.mValue <= 0) return s4x12();
219 constexpr s4x12 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)) >> 19));
286 }
287
289 return from_raw(static_cast<i16>(fl::cos32(angle_to_a24(angle)) >> 19));
290 }
291
292 // Combined sin+cos from s4x12 radians. Output in s4x12 [-1, 1].
293 static FASTLED_FORCE_INLINE void sincos(s4x12 angle, s4x12 &out_sin,
294 s4x12 &out_cos) FL_NOEXCEPT {
295 u32 a24 = angle_to_a24(angle);
296 out_sin = from_raw(static_cast<i16>(fl::sin32(a24) >> 19));
297 out_cos = from_raw(static_cast<i16>(fl::cos32(a24) >> 19));
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 (20 frac bits) to minimize
320 // rounding error, then converts back to 12 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 20 fractional bits. Max product ~2^33, fits i64 intermediate.
335 constexpr int IFRAC = 20;
336 constexpr i32 c0 = 1512456; // 1.44179 * 2^20
337 constexpr i32 c1 = -733024; // -0.69907 * 2^20
338 constexpr i32 c2 = 381136; // 0.36348 * 2^20
339 constexpr i32 c3 = -111776; // -0.10660 * 2^20
340 // Extend t from 12 to 20 frac bits.
341 i32 t20 = 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) * t20) >> IFRAC);
345 acc = c1 + static_cast<i32>((static_cast<i64>(acc) * t20) >> IFRAC);
346 acc = c0 + static_cast<i32>((static_cast<i64>(acc) * t20) >> IFRAC);
347 i32 frac_part = static_cast<i32>((static_cast<i64>(acc) * t20) >> IFRAC);
348 // Convert from 20 frac bits back to 12.
349 i16 frac12 = static_cast<i16>(frac_part >> (IFRAC - FRAC_BITS));
350 return from_raw(static_cast<i16>(static_cast<i32>(static_cast<u32>(int_part) << FRAC_BITS) + frac12));
351 }
352
353 // Fixed-point 2^x. Uses 4-term minimax polynomial for 2^t, t in [0,1).
354 // Horner evaluation uses i32 intermediates (20 frac bits) to minimize
355 // rounding error, then converts back to 12 frac bits.
357 s4x12 fl_val = floor(x);
358 s4x12 fr = x - fl_val;
359 i32 n = fl_val.mValue >> FRAC_BITS;
360 if (n >= INT_BITS - 1) return from_raw(0x7FFF);
361 if (n < -FRAC_BITS) return s4x12();
362 i32 int_pow;
363 if (n >= 0) {
364 int_pow = static_cast<i32>(SCALE) << n;
365 } else {
366 int_pow = static_cast<i32>(SCALE) >> (-n);
367 }
368 // 4-term minimax coefficients for 2^t - 1, t in [0,1).
369 // Stored as i32 with 20 fractional bits.
370 constexpr int IFRAC = 20;
371 constexpr i32 d0 = 726836; // 0.69316 * 2^20
372 constexpr i32 d1 = 252400; // 0.24071 * 2^20
373 constexpr i32 d2 = 55952; // 0.05336 * 2^20
374 constexpr i32 d3 = 13376; // 0.01276 * 2^20
375 // Extend fr from 12 to 20 frac bits.
376 i32 fr20 = static_cast<i32>(fr.mValue) << (IFRAC - FRAC_BITS);
377 // Horner: 1 + fr * (d0 + fr * (d1 + fr * (d2 + fr * d3)))
378 i32 acc = d3;
379 acc = d2 + static_cast<i32>((static_cast<i64>(acc) * fr20) >> IFRAC);
380 acc = d1 + static_cast<i32>((static_cast<i64>(acc) * fr20) >> IFRAC);
381 acc = d0 + static_cast<i32>((static_cast<i64>(acc) * fr20) >> IFRAC);
382 constexpr i32 one20 = static_cast<i32>(1) << IFRAC;
383 i32 frac_pow20 = one20 + static_cast<i32>((static_cast<i64>(acc) * fr20) >> IFRAC);
384 // Convert from 20 frac bits to 12 frac bits, then scale by int_pow.
385 i32 frac_pow12 = frac_pow20 >> (IFRAC - FRAC_BITS);
386 i32 result =
387 (int_pow * frac_pow12) >> FRAC_BITS;
388 return from_raw(static_cast<i16>(result));
389 }
390
391 // Converts s4x12 radians to sin32/cos32 input format.
392 // 256/(2*PI) — converts radians to sin32/cos32 format.
393 static constexpr i32 RAD_TO_24 = 2670177;
395 return static_cast<u32>(
396 (static_cast<i64>(angle.mValue) * RAD_TO_24) >> FRAC_BITS);
397 }
398
399 // Polynomial atan for t in [0, 1]. Returns [0, π/4].
400 // 7th-order minimax: atan(t) ≈ t * (c0 + t² * (c1 + t² * (c2 + t² * c3)))
401 // Coefficients optimized via coordinate descent on s16x16 quantization grid.
403 constexpr s4x12 c0(0.9998779297f);
404 constexpr s4x12 c1(-0.3269348145f);
405 constexpr s4x12 c2(0.1594085693f);
406 constexpr s4x12 c3(-0.0472106934f);
407 s4x12 t2 = t * t;
408 return t * (c0 + t2 * (c1 + t2 * (c2 + t2 * c3)));
409 }
410};
411
412} // namespace fl
413
constexpr bool operator<=(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:108
static FASTLED_FORCE_INLINE s4x12 atan_unit(s4x12 t) FL_NOEXCEPT
Definition s4x12.h:402
static FASTLED_FORCE_INLINE s4x12 acos(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:201
static FASTLED_FORCE_INLINE s4x12 pow(s4x12 base, s4x12 exp) FL_NOEXCEPT
Definition s4x12.h:217
friend constexpr s4x12 operator*(i16 scalar, s4x12 fp) FL_NOEXCEPT
Definition s4x12.h:100
static FASTLED_FORCE_INLINE s4x12 log2_fp(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:321
static constexpr FASTLED_FORCE_INLINE s4x12 clamp(s4x12 x, s4x12 lo, s4x12 hi) FL_NOEXCEPT
Definition s4x12.h:144
constexpr FASTLED_FORCE_INLINE int sign() const FL_NOEXCEPT
Definition s4x12.h:250
constexpr FASTLED_FORCE_INLINE s4x12 operator*(i16 scalar) const FL_NOEXCEPT
Definition s4x12.h:96
constexpr s4x12() FL_NOEXCEPT=default
constexpr float to_float() const FL_NOEXCEPT
Definition s4x12.h:61
constexpr bool operator<(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:106
constexpr i16 to_int() const FL_NOEXCEPT
Definition s4x12.h:60
constexpr FASTLED_FORCE_INLINE s4x12 floor() const FL_NOEXCEPT
Definition s4x12.h:234
static FASTLED_FORCE_INLINE s4x12 exp2_fp(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:356
static FASTLED_FORCE_INLINE s4x12 sin(s4x12 angle) FL_NOEXCEPT
Definition s4x12.h:284
static constexpr FASTLED_FORCE_INLINE s4x12 lerp(s4x12 a, s4x12 b, s4x12 t) FL_NOEXCEPT
Definition s4x12.h:140
FASTLED_FORCE_INLINE s4x12 sin() const FL_NOEXCEPT
Definition s4x12.h:254
constexpr FASTLED_FORCE_INLINE s4x12 operator-(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:80
static constexpr FASTLED_FORCE_INLINE s4x12 mod(s4x12 a, s4x12 b) FL_NOEXCEPT
Definition s4x12.h:115
constexpr FASTLED_FORCE_INLINE s4x12 operator+(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:75
static FASTLED_FORCE_INLINE s4x12 atan(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:163
constexpr bool operator==(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:110
FASTLED_FORCE_INLINE s4x12 cos() const FL_NOEXCEPT
Definition s4x12.h:258
constexpr FASTLED_FORCE_INLINE s4x12 operator>>(int shift) const FL_NOEXCEPT
Definition s4x12.h:90
constexpr FASTLED_FORCE_INLINE s4x12 rsqrt() const FL_NOEXCEPT
Definition s4x12.h:278
FASTLED_FORCE_INLINE s4x12 asin() const FL_NOEXCEPT
Definition s4x12.h:266
FASTLED_FORCE_INLINE s4x12 acos() const FL_NOEXCEPT
Definition s4x12.h:270
constexpr s4x12(IntT n) FL_NOEXCEPT
Definition s4x12.h:35
static constexpr int FRAC_BITS
Definition s4x12.h:22
constexpr FASTLED_FORCE_INLINE s4x12 ceil() const FL_NOEXCEPT
Definition s4x12.h:238
constexpr FASTLED_FORCE_INLINE s4x12 operator-() const FL_NOEXCEPT
Definition s4x12.h:85
constexpr s4x12(i16 raw, RawTag) FL_NOEXCEPT
Definition s4x12.h:51
constexpr FASTLED_FORCE_INLINE s4x12 operator/(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:70
static constexpr FASTLED_FORCE_INLINE s4x12 rsqrt(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:211
constexpr bool operator>(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:107
static constexpr FASTLED_FORCE_INLINE int sign(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:136
static constexpr i32 SCALE
Definition s4x12.h:23
static constexpr FASTLED_FORCE_INLINE s4x12 floor(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:119
constexpr FASTLED_FORCE_INLINE s4x12 abs() const FL_NOEXCEPT
Definition s4x12.h:246
static constexpr FASTLED_FORCE_INLINE s4x12 from_raw(i16 raw) FL_NOEXCEPT
Definition s4x12.h:53
static constexpr int INT_BITS
Definition s4x12.h:21
static FASTLED_FORCE_INLINE s4x12 smoothstep(s4x12 edge0, s4x12 edge1, s4x12 x) FL_NOEXCEPT
Definition s4x12.h:152
FASTLED_FORCE_INLINE s4x12 atan() const FL_NOEXCEPT
Definition s4x12.h:262
static constexpr FASTLED_FORCE_INLINE u32 angle_to_a24(s4x12 angle) FL_NOEXCEPT
Definition s4x12.h:394
constexpr s4x12(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 s4x12.h:40
constexpr i16 raw() const FL_NOEXCEPT
Definition s4x12.h:59
static FASTLED_FORCE_INLINE s4x12 asin(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:196
static constexpr int _highest_bit_step(u32 v, int r) FL_NOEXCEPT
Definition s4x12.h:308
static constexpr FASTLED_FORCE_INLINE int highest_bit(u32 v) FL_NOEXCEPT
Definition s4x12.h:304
static constexpr FASTLED_FORCE_INLINE s4x12 abs(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:132
constexpr FASTLED_FORCE_INLINE s4x12 sqrt() const FL_NOEXCEPT
Definition s4x12.h:274
static FASTLED_FORCE_INLINE void sincos(s4x12 angle, s4x12 &out_sin, s4x12 &out_cos) FL_NOEXCEPT
Definition s4x12.h:293
constexpr bool operator>=(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:109
static constexpr i32 RAD_TO_24
Definition s4x12.h:393
static constexpr FASTLED_FORCE_INLINE s4x12 step(s4x12 edge, s4x12 x) FL_NOEXCEPT
Definition s4x12.h:148
static constexpr FASTLED_FORCE_INLINE s4x12 fract(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:128
constexpr bool operator!=(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:111
static FASTLED_FORCE_INLINE s4x12 cos(s4x12 angle) FL_NOEXCEPT
Definition s4x12.h:288
constexpr FASTLED_FORCE_INLINE s4x12 fract() const FL_NOEXCEPT
Definition s4x12.h:242
static constexpr FASTLED_FORCE_INLINE s4x12 sqrt(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:206
i16 mValue
Definition s4x12.h:301
static constexpr FASTLED_FORCE_INLINE s4x12 ceil(s4x12 x) FL_NOEXCEPT
Definition s4x12.h:123
constexpr FASTLED_FORCE_INLINE s4x12 operator*(s4x12 b) const FL_NOEXCEPT
Definition s4x12.h:65
static FASTLED_FORCE_INLINE s4x12 atan2(s4x12 y, s4x12 x) FL_NOEXCEPT
Definition s4x12.h:177
#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