use*_*105 6 c++ bit-manipulation
我试图用C++编写一些关于"按位旋转"的代码,我想通过左边的shif来做这个.我不知道如何编写代码,但我在"维基百科"中找到了一些像这样的代码.
unsigned int rotl(unsigned int value, int shift) {
return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift));
}
Run Code Online (Sandbox Code Playgroud)
然后我试着让它工作,但是这段代码没有给出我期望的输出.防爆.我有数字unsigned int 12
,在二进制1100中,当我想用左shif按上面的代码进行按位旋转时,输出是和unsigned int 24
(11000),它必须给出输出unsigned int 9
,因为如果我进行按位旋转(左shif),第一个MSB位现在必须是第一位,所有其他位必须向左移动一位.
你能帮助理解那是什么问题吗?或者我做错了什么.
谢谢.
以下代码效果很好
#include <cstdint>
std::uint32_t rotl(std::uint32_t v, std::int32_t shift) {
std::int32_t s = shift>=0? shift%32 : -((-shift)%32);
return (v<<s) | (v>>(32-s));
}
std::uint32_t rotr(std::uint32_t v, std::int32_t shift) {
std::int32_t s = shift>=0? shift%32 : -((-shift)%32);
return (v>>s) | (v<<(32-s));
}
Run Code Online (Sandbox Code Playgroud)
当然还有它的测试.
#include <iostream>
int main(){
using namespace std;
cout<<rotr(8,1)<<endl; // 4
cout<<rotr(8,-1)<<endl; //16
cout<<rotl(8,1)<<endl; //16
cout<<rotl(8,-1)<<endl; //4
cout<<rotr(4,60)<<endl; //64
cout<<rotr(4,61)<<endl; //32
cout<<rotl(4,3)<<endl; //32
cout<<rotl(4,4)<<endl; //64
return 0;
}
Run Code Online (Sandbox Code Playgroud)
也许我没有提供最快的实现,但肯定是一个便携和稳定的实现
通用版本
#include <cstdint>
template< class T>
inline T rotl( T v, std::int32_t shift){
std::size_t m = sizeof(v)*std::numeric_limits<T>::digits;
T s = shift>=0? shift%m: -((-shift)%m)
return (v<<s) | (v>>(m-s));
}
template< class T>
inline T rotr( T v, std::int32_t shift){
std::size_t m = sizeof(v)*std::numeric_limits<T>::digits;
T s = shift>=0? shift%m: -((-shift)%m)
return (v>>s) | (v<<(m-s));
}
Run Code Online (Sandbox Code Playgroud)
干杯:)
C++20在头文件中提供了std::rotl
and 。来自cppreference.com的示例:std::rotr
<bit>
#include <bit>
#include <bitset>
#include <cstdint>
#include <iostream>
int main()
{
std::uint8_t i = 0b00011101;
std::cout << "i = " << std::bitset<8>(i) << '\n';
std::cout << "rotl(i,0) = " << std::bitset<8>(std::rotl(i,0)) << '\n';
std::cout << "rotl(i,1) = " << std::bitset<8>(std::rotl(i,1)) << '\n';
std::cout << "rotl(i,4) = " << std::bitset<8>(std::rotl(i,4)) << '\n';
std::cout << "rotl(i,9) = " << std::bitset<8>(std::rotl(i,9)) << '\n';
std::cout << "rotl(i,-1) = " << std::bitset<8>(std::rotl(i,-1)) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我相信std::bitset
在此示例中仅使用其流格式。