我有一些代码,可以使用左移运算符将各种长度的参数(u8、u16、u32)填充到 u64 中。
然后在代码中的各个地方我需要从这个臃肿的大参数中获取原始参数。
只是想知道,在代码中,我们应该如何确保它是逻辑右移而不是算术右移,同时返回原始参数。
所以问题是有没有#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
一般规则是逻辑移位适用于无符号二进制数,而算术移位适用于有符号 2 的补数。这将取决于你的编译器(gcc等),而不是语言,但你可以假设编译器将对无符号数字使用逻辑移位......所以如果你有一个无符号类型,人们会认为它将是一个逻辑转移。
如果您需要编译器之间的可移植性,您始终可以编写自己的方法来检查并进行转换。或者您可以使用内联汇编来执行此操作并避免任何问题(但您将被固定到一个平台)。
简而言之,要 100% 正确,请检查您的编译器 doco。
这看起来像 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