C ++中的Bit Shifting产生了错误的答案

时间:2014-06-07 18:57:09

标签: c++ shift

我尝试运行以下代码:

char c = (2 << 7) >> 7

应返回0,因为2将此二进制表示形式设为char

0 0 0 0 0 0 1 0

离开7班后,我们得到

0 0 0 0 0 0 0 0

然后,在七个班次之后,我们得到

0 0 0 0 0 0 0 0

但是,我得到的结果是2,而不是0。

编译器说2 << 7是256,但它是char,因此它不应该是256。

我了解2 << 7将计算为int s,答案将放入c,因此256 >> 7为2。

我尝试将2转换为char(例如:(char)2>>7),但它也不起作用。

我正在尝试从char中提取每个位,所以我写了这段代码:

char c = 0x02;
for(int i=0;i<7;i++)
{
    char current = (c<<i)>>7;
}

我怎样才能得到每一位?我的方式有什么问题?

3 个答案:

答案 0 :(得分:7)

C ++中一个操作数为int的算术移位操作的结果始终为int。因此,当你写

current = (c << i) >> 7;

C ++会将(c << i)(c << i) >> 7解释为int s,仅在分配完成后返回char。由于临时值为int s,因此不会发生溢出,结果应该是转换为char的整数结果。

希望这有帮助!

答案 1 :(得分:4)

要获得每一位,你可以写:

(c >> i) & 0x01

优点:适用于任何整数类型。

答案 2 :(得分:4)

根据5.8 [expr.shift]第1段:

  

......操作数应为整数或无范围的枚举类型,并执行整体促销。结果的类型是提升的左操作数的类型。 ...

这对于类型为char的左参数以及整数提升规则(4.5 [conv.prom])表示结果为int。当然,int可以保留2 << 7的结果。您也可以轻松验证此行为:

#include <iostream>

void print(char c) { std::cout << "char=" << int(c) << "\n"; }
void print(int i) { std::cout << "int=" << i << "\n"; }

int main()
{
    print(2 << 7);
}

获取值的最简单方法是使用std::bitset<N> N作为相应无符号类型的数字,例如:

char c('a');
std::bitset<std::numeric_limits<unsigned char>::digits> bits(c);

如果你想自己获取比特,你可以使用整数类型的unsigned对应物掩盖这些比特,例如:

template <typename T>
void get_bits(T val)
{
    typedef typename std::make_unsigned<T>::type U;
    U value(val);
    for (std::size_t s(std::numeric_limits<U>::digits); s-- != 0; ) {
        std::cout << bool(value & (1u << s));
    }
    std::cout << '\n';
}