我有一个屏蔽程序(为给定大小的下半部分创建一个全位掩码):
template<class T>
T bottom_half() {
T halfway = ((sizeof(T) * 8) / 2);
T mask = (1 << halfway) - 1;
return mask;
}
如果我拨打bottom_half<int>()
或long
或char
,则可以正常使用。但由于某些原因,当我使用long long
运行时,halfway
已正确设置为32
,但mask
为0
。为什么会这样?
答案 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
投射到正确的类型。实际上,它是一个简单的整数,所以这种转变没有任何结果 - 你将这一点从存在中移开。