我想对一个变量进行位移,并将一个位移出一个布尔值。
类似的东西:
unsigned int i = 1;
bool b = rshift(&i); // i now equals 0 and b is set to true
如何实现这一目标?
答案 0 :(得分:13)
你必须在班次之前捕捉位
bool rshift(unsigned int* p) {
bool ret = (*p) & 1;
*p >>= 1;
return ret;
}
答案 1 :(得分:5)
你没有。你必须在班次之前测试它:
bool
rshift( unsigned& i )
{
bool results = (i & 0x01) != 0;
i >>= 1;
return results;
}
(这对于右移是很简单的。对于左移,你必须知道 单词中的位数。)
答案 2 :(得分:3)
要为任何班次和任何类型执行此操作,请执行相反操作(以检查是否丢失了某些内容)。
template <typename T> bool rshift(T& val) {
T const original = val;
return ((val >>= 1) << 1) != original;
}
template <typename T> bool lshift(T& val) {
T const original = val;
return ((val <<= 1) >> 1) != original;
}
答案 3 :(得分:1)
如果您正在寻找旋转功能,可以尝试以下操作。
首先,有一个元函数来获取待旋转值的位数(注意:8*sizeof(T)
不可移植;标准只能指定至少8位):
#include <climits>
template <typename T>
struct bits { enum { value = CHAR_BIT * sizeof(T) }; };
接下来,定义一个正确旋转的功能。它通过按预期应用右移来实现这一目的,并通过左移来提升将被取消的内容:
template <unsigned int N, typename T>
T rotate_right (T value)
{
enum { left = bits<T>::value - N };
return (value>>N) | (value<<left);
}
具有测试和测试的诊断功能:
#include <iostream>
template <typename T>
void print_bits (std::ostream &os, T value)
{
for (unsigned int i=bits<T>::value; i!=0; --i)
os << ((value>>(i-1))&1);
}
int main () {
char c = 1,
c_ = rotate_right<1>(c);
unsigned long long ull = 0xF0F0C0C050503030,
ull_ = rotate_right<63>(ull);
std::cout << "c ="; print_bits(std::cout, c); std::cout << '\n';
std::cout << "c'="; print_bits(std::cout, c_); std::cout << '\n';
std::cout << "ull ="; print_bits(std::cout, ull); std::cout << '\n';
std::cout << "ull'="; print_bits(std::cout, ull_); std::cout << '\n';
}
输出:
c =00000001
c'=10000000
ull =1111000011110000110000001100000001010000010100000011000000110000
ull'=1110000111100001100000011000000010100000101000000110000001100001
左旋转可以类似地实现,也可以实现右旋转。
至于性能,g ++检测成语并在x86和amd64上使用旋转指令。
g++ -std=c++0x -S main.cc
cat main.s
...
sarl %eax
...
答案 4 :(得分:0)
以下是目前提出的建议的替代方案:
bool rshift(int32_t &i) {
long long i2 = (static_cast<int64_t>(i) << 31);
i = (i2 >> 32);
return static_cast<int32_t>(i2);
}
这假定int
是int
这些天通常所说的内容,即int32_t
。它将其复制到int64_t
,然后执行移位,将高32位复制到i
,然后将低32位(包含移位的1
)作为布尔值返回。 / p>
我不知道这是否比其他方法更快。这种通用方法的附加好处是它可以用于检索多个比特,例如如果你换2位或更多位。