From 4601da4ab914a0e55e670b7f64d78a3e0675516c Mon Sep 17 00:00:00 2001 From: sukibaby <163092272+sukibaby@users.noreply.github.com> Date: Sat, 8 Feb 2025 22:59:36 -0800 Subject: [PATCH] Update RageUtil::power_of_two Replacing the SM5 power-of-two code with the implementation from Bit Twiddling Hacks, since the current implementation isn't correctly handling the edge case where the input is 0, and is a little overcomplicated. --- src/RageUtil.cpp | 32 ++++++++++++++------------------ src/RageUtil.h | 2 +- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/RageUtil.cpp b/src/RageUtil.cpp index a057d5d956..d985a1e3f8 100644 --- a/src/RageUtil.cpp +++ b/src/RageUtil.cpp @@ -122,25 +122,21 @@ float fmodfp(float x, float y) return x; } -int power_of_two( int input ) +/* https://graphics.stanford.edu/%7Eseander/bithacks.html#RoundUpPowerOf2 */ +int power_of_two( int v ) { - int exp = 31, i = input; - if (i >> 16) - i >>= 16; - else exp -= 16; - if (i >> 8) - i >>= 8; - else exp -= 8; - if (i >> 4) - i >>= 4; - else exp -= 4; - if (i >> 2) - i >>= 2; - else exp -= 2; - if (i >> 1 == 0) - exp -= 1; - int value = 1 << exp; - return (input == value) ? value : (value << 1); + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + + /* Always be sure to return a value of at least 1. In the event of any edge + * cases, such as a zero or negative input, the returned value will be `1`. */ + v += (v == 0); + return v; } bool IsAnInt( const RString &s ) diff --git a/src/RageUtil.h b/src/RageUtil.h index 56fb7f67ad..eb97cc5c5f 100644 --- a/src/RageUtil.h +++ b/src/RageUtil.h @@ -328,7 +328,7 @@ void fapproach( float& val, float other_val, float to_move ); /* Return a positive x mod y. */ float fmodfp( float x, float y ); -int power_of_two( int input ); +int power_of_two( int v ); bool IsAnInt( const RString &s ); bool IsHexVal( const RString &s ); RString BinaryToHex( const void *pData_, size_t iNumBytes );