Browse Source

Added a bit-twiddling helper method: findHighestSetBit()

tags/2021-05-28
jules 8 years ago
parent
commit
fcd5a47d8c
2 changed files with 29 additions and 23 deletions
  1. +20
    -20
      modules/juce_core/maths/juce_BigInteger.cpp
  2. +9
    -3
      modules/juce_core/maths/juce_MathsFunctions.h

+ 20
- 20
modules/juce_core/maths/juce_BigInteger.cpp View File

@@ -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)
#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
}
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 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;
}


+ 9
- 3
modules/juce_core/maths/juce_MathsFunctions.h View File

@@ -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
{


Loading…
Cancel
Save