diff options
author | zaaarf <me@zaaarf.foo> | 2024-01-02 13:56:42 +0100 |
---|---|---|
committer | zaaarf <me@zaaarf.foo> | 2024-01-02 15:34:47 +0100 |
commit | 255f85c12d104f7f7b12bd69892a1c993885451d (patch) | |
tree | c3c80de88789711e432423c023eb63be1460a5d9 /src | |
parent | 66b80459c9d49895de902432bce11176b1270878 (diff) |
feat: integer and fixed point square root functions
Diffstat (limited to 'src')
-rw-r--r-- | src/openvic-simulation/types/fixed_point/FixedPoint.hpp | 6 | ||||
-rw-r--r-- | src/openvic-simulation/utility/NumberUtils.hpp | 29 |
2 files changed, 33 insertions, 2 deletions
diff --git a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp index 75abefb..8d3a74b 100644 --- a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp +++ b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp @@ -209,6 +209,12 @@ namespace OpenVic { return !is_negative() ? value : -value; } + constexpr fixed_point_t sqrt() const { + return !is_negative() + ? static_cast<int64_t>(NumberUtils::sqrt(static_cast<uint64_t>(value) << PRECISION)) + : 0; + } + // Doesn't account for sign, so -n.abc -> 1 - 0.abc constexpr fixed_point_t get_frac() const { return value & (ONE - 1); diff --git a/src/openvic-simulation/utility/NumberUtils.hpp b/src/openvic-simulation/utility/NumberUtils.hpp index 6211772..d814019 100644 --- a/src/openvic-simulation/utility/NumberUtils.hpp +++ b/src/openvic-simulation/utility/NumberUtils.hpp @@ -9,7 +9,7 @@ namespace OpenVic::NumberUtils { return (num > 0.0) ? (num + 0.5) : (num - 0.5); } - constexpr uint64_t pow(uint64_t base, size_t exponent) { + constexpr uint64_t pow(uint64_t base, std::size_t exponent) { uint64_t ret = 1; while (exponent-- > 0) { ret *= base; @@ -17,11 +17,36 @@ namespace OpenVic::NumberUtils { return ret; } - constexpr int64_t pow(int64_t base, size_t exponent) { + constexpr int64_t pow(int64_t base, std::size_t exponent) { int64_t ret = 1; while (exponent-- > 0) { ret *= base; } return ret; } + + constexpr uint64_t sqrt(uint64_t n) { + uint64_t x = n; + uint64_t c = 0; + uint64_t d = 1ull << 62; + + while (d > n) + d >>= 2; + + for (; d != 0; d >>= 2) { + if (x >= c + d) { + x -= c + d; + c = (c >> 1) + d; + } else { + c >>= 1; + } + } + + //round up + if (x > 0) { + c += 1; + } + + return c; + } } |