我有一些代码用不同长度的参数(u8,u16,u32)填充到带左移位运算符的u64中。
然后在代码中的不同位置,我需要从这个大膨胀参数中取回原始参数。
只是想知道在代码中,我们应该如何确保它的逻辑右移而不是算术,同时取回原始参数。
所以qestion是否有任何#defs或其他方法来确保并检查编译器是否会搞砸?
这是C ++代码:
u32 x , y ,z;
u64 uniqID = 0;
u64 uniqID = (s64) x << 54 |
(s64) y << 52 |
(s64) z << 32 |
uniqID; // the original uniqID value.
稍后在获取价值时:
z= (u32) ((uniqID >> 32 ) & (0x0FFFFF)); //20 bits
y= (u32) ((uniqID >> (52 ) & 0x03)); //2 bits
x= (u32) ((uniqID >> (54) & 0x03F)); //6 bits
答案 0 :(得分:1)
一般规则是逻辑移位适用于无符号二进制数,而算术移位适用于带符号2的comp数。这将取决于你的编译器(gcc等),而不是语言,但你可以假设编译器将使用无符号数字的逻辑移位...所以如果你有一个无符号类型,人们会认为它将是一个逻辑转变。
如果您需要编译器之间的某些可移植性,您始终可以编写自己的方法来检查并进行转换。或者您可以使用内联asm来执行此操作并避免任何问题(但您将被修复到平台)。
简而言之,要100%正确,请检查您的编译器doco。
答案 1 :(得分:1)
这看起来像C / C ++,所以只需确保uniqID
是无符号整数类型。
或者,只需投下它:
z = (u32) ( ((unsigned long long)uniqID >> (32) & (0x0FFFFF)); //20 bits
y = (u32) ( ((unsigned long long)uniqID >> (52) & 0x03)) ; //2 bits
x = (u32) ( ((unsigned long long)uniqID >> (54) & 0x03F)) ; //6 bits