Какой самый простой способ проверить, является ли число в C ++ степенью двойки?
Если у вас есть современный процессор Intel с инструкциями по обработке битов , вы можете выполнить следующее. Он опускает прямой код C / C ++, потому что на него уже ответили другие, но он вам нужен, если BMI недоступен или включен.
bool IsPowerOf2_32(uint32_t x)
{
#if __BMI__ || ((_MSC_VER >= 1900) && defined(__AVX2__))
return !!((x > 0) && _blsr_u32(x));
#endif
}
bool IsPowerOf2_64(uint64_t x)
{
#if __BMI__ || ((_MSC_VER >= 1900) && defined(__AVX2__))
return !!((x > 0) && _blsr_u64(x));
#endif
}
GCC, ICC и Clang поддерживают BMI сигналов с __BMI__
. Он доступен в компиляторах Microsoft в Visual Studio 2015 и выше, когда доступен и включен AVX2. . Чтобы узнать, какие заголовки вам нужны, см. Заголовочные файлы для встроенных функций SIMD .
Я обычно охранник _blsr_u64
с _LP64_
в случае компиляции на i686. Clang нуждается в небольшом обходном пути, потому что он использует немного другой внутренний символ nam:
#if defined(__GNUC__) && defined(__BMI__)
# if defined(__clang__)
# ifndef _tzcnt_u32
# define _tzcnt_u32(x) __tzcnt_u32(x)
# endif
# ifndef _blsr_u32
# define _blsr_u32(x) __blsr_u32(x)
# endif
# ifdef __x86_64__
# ifndef _tzcnt_u64
# define _tzcnt_u64(x) __tzcnt_u64(x)
# endif
# ifndef _blsr_u64
# define _blsr_u64(x) __blsr_u64(x)
# endif
# endif
# endif
#endif
Можете ли вы назвать мне хороший веб-сайт, где можно найти такой алгоритм?
Этот сайт часто цитируют: Bit Twiddling Hacks .