Quelle est la manière la plus simple de tester si un nombre est une puissance de 2 en C ++?
Si vous disposez d'un processeur Intel moderne avec les instructions de manipulation des bits , vous pouvez effectuer les opérations suivantes. Il omet le code C / C ++ simple car d'autres y ont déjà répondu, mais vous en avez besoin si l'IMC n'est pas disponible ou activé.
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
}
Prise en charge de l'IMC des signaux GCC, ICC et Clang avec __BMI__
. Il est disponible dans les compilateurs Microsoft dans Visual Studio 2015 et versions ultérieures lorsque AVX2 est disponible et activé . Pour les en-têtes dont vous avez besoin, voir Fichiers d'en-tête pour les intrinsèques SIMD .
Je garde généralement le _blsr_u64
avec un _LP64_
en cas de compilation sur i686. Clang a besoin d'une petite solution de contournement car il utilise un nom de symbole intrinsèque légèrement différent:
#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
Pouvez-vous me dire un bon site Web où trouver ce type d'algorithme?
Ce site est souvent cité: Bit Twiddling Hacks .