¿Cuál es la forma más sencilla de probar si un número es una potencia de 2 en C ++?
Si tiene un procesador Intel moderno con las instrucciones de manipulación de bits , puede realizar lo siguiente. Omite el código C / C ++ directo porque otros ya lo han respondido, pero lo necesita si BMI no está disponible o habilitado.
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 y Clang señalan el soporte de BMI con __BMI__
. Está disponible en los compiladores de Microsoft en Visual Studio 2015 y versiones posteriores cuando AVX2 está disponible y habilitado . Para conocer los encabezados que necesita, consulte Archivos de encabezado para conocer los elementos intrínsecos de SIMD .
Normalmente lo guardo _blsr_u64
con un _LP64_
en caso de compilar en i686. Clang necesita una pequeña solución porque usa un nam de símbolo intrínseco ligeramente diferente:
#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
¿Puede decirme un buen sitio web donde se pueda encontrar este tipo de algoritmo?
Este sitio web se cita a menudo: Bit Twiddling Hacks .