From fcd5a47d8c62a036d43298b102eb9d9371e1dbdd Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 11 Jan 2017 08:50:16 +0000 Subject: [PATCH] Added a bit-twiddling helper method: findHighestSetBit() --- modules/juce_core/maths/juce_BigInteger.cpp | 38 +++++++++---------- modules/juce_core/maths/juce_MathsFunctions.h | 12 ++++-- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/modules/juce_core/maths/juce_BigInteger.cpp b/modules/juce_core/maths/juce_BigInteger.cpp index c0aab6228b..fa973a4be6 100644 --- a/modules/juce_core/maths/juce_BigInteger.cpp +++ b/modules/juce_core/maths/juce_BigInteger.cpp @@ -33,26 +33,26 @@ namespace inline uint32 bitToMask (const int bit) noexcept { return (uint32) 1 << (bit & 31); } inline size_t bitToIndex (const int bit) noexcept { return (size_t) (bit >> 5); } inline size_t sizeNeededToHold (int highestBit) noexcept { return (size_t) (highestBit >> 5) + 1; } +} - inline int highestBitInInt (uint32 n) noexcept - { - jassert (n != 0); // (the built-in functions may not work for n = 0) +int findHighestSetBit (uint32 n) noexcept +{ + jassert (n != 0); // (the built-in functions may not work for n = 0) - #if JUCE_GCC || JUCE_CLANG - return 31 - __builtin_clz (n); - #elif JUCE_MSVC - unsigned long highest; - _BitScanReverse (&highest, n); - return (int) highest; - #else - n |= (n >> 1); - n |= (n >> 2); - n |= (n >> 4); - n |= (n >> 8); - n |= (n >> 16); - return countBitsInInt32 (n >> 1); - #endif - } + #if JUCE_GCC || JUCE_CLANG + return 31 - __builtin_clz (n); + #elif JUCE_MSVC + unsigned long highest; + _BitScanReverse (&highest, n); + return (int) highest; + #else + n |= (n >> 1); + n |= (n >> 2); + n |= (n >> 4); + n |= (n >> 8); + n |= (n >> 16); + return countNumberOfBits (n >> 1); + #endif } //============================================================================== @@ -393,7 +393,7 @@ int BigInteger::getHighestBit() const noexcept for (int i = (int) bitToIndex (highestBit); i >= 0; --i) if (uint32 n = values[i]) - return highestBitInInt (n) + (i << 5); + return findHighestSetBit (n) + (i << 5); return -1; } diff --git a/modules/juce_core/maths/juce_MathsFunctions.h b/modules/juce_core/maths/juce_MathsFunctions.h index 29bcc6a55b..dd416aeeb9 100644 --- a/modules/juce_core/maths/juce_MathsFunctions.h +++ b/modules/juce_core/maths/juce_MathsFunctions.h @@ -452,7 +452,7 @@ inline int roundToInt (int value) noexcept This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works fine for values above zero, but negative numbers are rounded the wrong way. */ -inline int roundToIntAccurate (const double value) noexcept +inline int roundToIntAccurate (double value) noexcept { #ifdef __INTEL_COMPILER #pragma float_control (pop) @@ -472,7 +472,7 @@ inline int roundToIntAccurate (const double value) noexcept even numbers will be rounded up or down differently. For a more accurate conversion, see roundDoubleToIntAccurate(). */ -inline int roundDoubleToInt (const double value) noexcept +inline int roundDoubleToInt (double value) noexcept { return roundToInt (value); } @@ -487,7 +487,7 @@ inline int roundDoubleToInt (const double value) noexcept rounding values whose floating point component is exactly 0.5, odd numbers and even numbers will be rounded up or down differently. */ -inline int roundFloatToInt (const float value) noexcept +inline int roundFloatToInt (float value) noexcept { return roundToInt (value); } @@ -512,6 +512,12 @@ inline int nextPowerOfTwo (int n) noexcept return n + 1; } +/** Returns the index of the highest set bit in a (non-zero) number. + So for n=3 this would return 1, for n=7 it returns 2, etc. + An input value of 0 is illegal! +*/ +int findHighestSetBit (uint32 n) noexcept; + /** Returns the number of bits in a 32-bit integer. */ inline int countNumberOfBits (uint32 n) noexcept {