Cách đơn giản nhất để kiểm tra xem một số có phải là lũy thừa của 2 trong C ++ hay không?
Nếu bạn có bộ xử lý Intel hiện đại với Hướng dẫn thao tác bit , thì bạn có thể thực hiện các thao tác sau. Nó bỏ qua mã C / C ++ thông thường vì những người khác đã trả lời nó, nhưng bạn cần nó nếu BMI không có sẵn hoặc không được kích hoạt.
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
}
Hỗ trợ BMI tín hiệu GCC, ICC và Clang với __BMI__
. Nó có sẵn trong trình biên dịch của Microsoft trong Visual Studio 2015 trở lên khi AVX2 có sẵn và được kích hoạt . Đối với các tiêu đề bạn cần, hãy xem Tệp tiêu đề để biết bản chất của SIMD .
Tôi thường bảo vệ _blsr_u64
bằng một _LP64_
biên dịch trong trường hợp trên i686. Clang cần một chút cách giải quyết vì nó sử dụng một biểu tượng nội tại hơi khác 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
Bạn có thể cho tôi biết một trang web tốt có thể tìm thấy loại thuật toán này không?
Trang web này thường được trích dẫn: Bit Twiddling Hacks .