1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 13:27:35 +00:00

AK: Add FixedPoint base 2 logarithm

The log base 2 is implemented using the binary logarithm algorithm
by Clay Turner (see the link in the comment)
This commit is contained in:
kleines Filmröllchen 2022-02-15 00:38:54 +01:00 committed by Andreas Kling
parent 30002c2ccb
commit 98058f7efe
2 changed files with 48 additions and 0 deletions

View file

@ -8,7 +8,9 @@
#include <AK/Concepts.h>
#include <AK/Format.h>
#include <AK/IntegralMath.h>
#include <AK/Math.h>
#include <AK/NumericLimits.h>
#include <AK/Types.h>
namespace AK {
@ -116,6 +118,39 @@ public:
: 0);
}
// http://www.claysturner.com/dsp/BinaryLogarithm.pdf
constexpr This log2() const
{
// 0.5
This b = create_raw(1 << (precision - 1));
This y = 0;
This x = *this;
// FIXME: There's no negative infinity.
if (x.raw() <= 0)
return create_raw(NumericLimits<Underlying>::min());
if (x != 1) {
i32 shift_amount = AK::log2<Underlying>(x.raw()) - precision;
if (shift_amount > 0)
x >>= shift_amount;
else
x <<= -shift_amount;
y += shift_amount;
}
for (size_t i = 0; i < precision; ++i) {
x *= x;
if (x >= 2) {
x >>= 1;
y += b;
}
b >>= 1;
}
return y;
}
constexpr bool signbit() const requires(IsSigned<Underlying>)
{
return m_value >> (sizeof(Underlying) * 8 - 1);