FastLED 3.9.15
Loading...
Searching...
No Matches
isqrt.h
Go to the documentation of this file.
1#pragma once
2
3// Integer square root for fixed-point types.
4// Bit-by-bit algorithm — no float, no division.
5//
6// C++11 constexpr functions cannot contain loops, so the algorithm is
7// expressed as tail recursion. In C++14+ this would just be a loop,
8// but FastLED targets C++11 for broad platform support (AVR, ESP32,
9// etc.). Without intervention, compilers at low optimization levels
10// (-O0, -O1) emit actual recursive calls — stack frames per iteration.
11//
12// FL_OPTIMIZE_FUNCTION forces per-function optimization to ensure the
13// tail recursion is converted to forward iteration (loops) regardless
14// of the global optimization level:
15// GCC: __attribute__((optimize("O3"))) — verified to produce
16// tight iterative loops even at -O0.
17// Clang: __attribute__((hot)) — best-effort hint; Clang converts
18// recursion to loops at -O2+ but not at -O0/-O1. This only
19// affects the host test build; all embedded targets use GCC.
20
21#include "fl/stl/compiler_control.h" // FL_OPTIMIZE_FUNCTION
22#include "fl/stl/int.h"
23#include "fl/stl/noexcept.h"
24
26
27namespace fl {
28
30 return (bit == 0 || bit <= x) ? bit : _isqrt64_start(x, bit >> 2);
31}
32
34 return bit == 0
35 ? static_cast<u32>(result)
36 : (x >= result + bit)
37 ? _isqrt64_step(x - (result + bit), (result >> 1) + bit, bit >> 2)
38 : _isqrt64_step(x, result >> 1, bit >> 2);
39}
40
41FL_OPTIMIZE_FUNCTION constexpr inline u32 _isqrt32_start(u32 x, u32 bit) FL_NOEXCEPT {
42 return (bit == 0 || bit <= x) ? bit : _isqrt32_start(x, bit >> 2);
43}
44
45FL_OPTIMIZE_FUNCTION constexpr inline u16 _isqrt32_step(u32 x, u32 result, u32 bit) FL_NOEXCEPT {
46 return bit == 0
47 ? static_cast<u16>(result)
48 : (x >= result + bit)
49 ? _isqrt32_step(x - (result + bit), (result >> 1) + bit, bit >> 2)
50 : _isqrt32_step(x, result >> 1, bit >> 2);
51}
52
53FL_OPTIMIZE_FUNCTION constexpr inline u16 isqrt32(u32 x) FL_NOEXCEPT {
54 return x == 0 ? u16(0)
55 : _isqrt32_step(x, 0, _isqrt32_start(x, u32(1) << 30));
56}
57
59 return x == 0 ? u32(0)
60 : _isqrt64_step(x, 0, _isqrt64_start(x, u64(1) << 62));
61}
62
63} // namespace fl
64
FL_OPTIMIZE_FUNCTION constexpr u16 _isqrt32_step(u32 x, u32 result, u32 bit) FL_NOEXCEPT
Definition isqrt.h:45
FL_OPTIMIZE_FUNCTION constexpr u64 _isqrt64_start(u64 x, u64 bit) FL_NOEXCEPT
Definition isqrt.h:29
FL_OPTIMIZE_FUNCTION constexpr u32 _isqrt64_step(u64 x, u64 result, u64 bit) FL_NOEXCEPT
Definition isqrt.h:33
FL_OPTIMIZE_FUNCTION constexpr u32 _isqrt32_start(u32 x, u32 bit) FL_NOEXCEPT
Definition isqrt.h:41
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
fl::u64 u64
Definition s16x16x4.h:221
FL_OPTIMIZE_FUNCTION constexpr u16 isqrt32(u32 x) FL_NOEXCEPT
Definition isqrt.h:53
FL_OPTIMIZE_FUNCTION constexpr u32 isqrt64(u64 x) FL_NOEXCEPT
Definition isqrt.h:58
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_OPTIMIZATION_LEVEL_O3_BEGIN
#define FL_OPTIMIZATION_LEVEL_O3_END
#define FL_OPTIMIZE_FUNCTION
#define FL_NOEXCEPT