位掩码和长长的

时间:2013-09-17 18:24:38

标签: c++

我有一个屏蔽程序(为给定大小的下半部分创建一个全位掩码):

template<class T>
T bottom_half() {
    T halfway = ((sizeof(T) * 8) / 2);
    T mask = (1 << halfway) - 1;

    return mask;
}

如果我拨打bottom_half<int>()longchar,则可以正常使用。但由于某些原因,当我使用long long运行时,halfway已正确设置为32,但mask0。为什么会这样?

3 个答案:

答案 0 :(得分:8)

左移位移1,默认为int,机器上可能为32位。当你转移1<<32时,结果是未定义的,这意味着它不再可预测,因为它可能是任何东西。

在某些处理器上,1<<32可能会导致该位从整数的高端移位并导致0.在其他处理器上,32位移模数为寄存器大小,因此有效的是零位移,结果是1.无论如何,它是未定义的。

(有关此问题的讨论,请参阅What's bad about shifting a 32-bit variable 32 bits?。)

另请注意sizeof返回单位char或&#34;字节&#34; (这些在C中定义为相同,sizeof(char) == 1总是),但C不保证字节是8位。标准宏CHAR_BIT用于获取char的位大小。

试试这个

#include <limits.h>

template<class T>
T bottom_half() {
    T halfway = ((sizeof(T) * CHAR_BIT) / 2);
    T mask = ((T)1 << halfway) - 1;

    return mask;
}

答案 1 :(得分:3)

表达式1 << x的类型为int。左移有符号类型使得该值超过最大可表示值具有未定义的行为。请改用T(1) << x

答案 2 :(得分:0)

将您的班次操作中的1投射到正确的类型。实际上,它是一个简单的整数,所以这种转变没有任何结果 - 你将这一点从存在中移开。