Який найпростіший спосіб перевірити, чи число є ступенем 2 в C ++?
Якщо у вас є сучасний процесор Intel з інструкціями щодо маніпулювання бітами , ви можете виконати наступне. Він опускає прямий код C / C ++, оскільки на нього вже відповіли інші, але він потрібен, якщо ІМТ недоступний або ввімкнений.
bool IsPowerOf2_32(uint32_t x)
{
#if __BMI__ || ((_MSC_VER >= 1900) && defined(__AVX2__))
return !!((x > 0) && _blsr_u32(x));
#endif
// Fallback to C/C++ code
}
bool IsPowerOf2_64(uint64_t x)
{
#if __BMI__ || ((_MSC_VER >= 1900) && defined(__AVX2__))
return !!((x > 0) && _blsr_u64(x));
#endif
// Fallback to C/C++ code
}
GCC, ICC та Clang сигналізують про підтримку ІМТ за допомогою __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 // x86_64
# endif // Clang
#endif // GNUC and BMI
Чи можете ви сказати мені хороший веб-сайт, де можна знайти такий алгоритм?
Цей веб-сайт часто цитують: Bit Twiddling Hacks .