开发者

Arithmetic vs logical shift operation in C++

I have some code that stuffs in parameters of various length (u8, u16, u32) into a u64 with the left shift operator.

Then at various places in the code i need to get back the original parameters from this big bloated parameter.

Just wondering how , in the code, should we ensure that its a logical right shift and not arithmetic one while getting back the original parameters.

So the qestion is are there any #defs or other ways to ensure and check whether the compiler will screw up?

Here's the C++ code:

u32 x , y ,z;
u64 uniqID = 0;
u64 uniqID = (s64) x << 54 |
             (s64) y << 52 |
             (s64) z << 32 |
             uniqID;  // the 开发者_运维技巧original uniqID value.

And later on while getting the values back :

z= (u32) ((uniqID >> 32 ) & (0x0FFFFF)); //20 bits 
y= (u32) ((uniqID >> (52 ) & 0x03));     //2 bits
x= (u32) ((uniqID >> (54) & 0x03F));     //6 bits


The general rule is a logical shift is suitable for unsigned binary numbers, while the arithmetic shift is suitable for signed 2's comp numbers. It will depend on your compiler (gcc etc), not so much the language, but you can assume that the compiler will use a logical shift for unsigned numbers... So if you have an unsigned type one would think that it will be a logical shift.

You can always write your own method to check and do the shifting if you need some portability between compilers. Or you can use in-line asm to do this and avoid any issues (but you would be fixed to a platform).

In short to be 100% correct check your compiler doco.


This looks like C/C++, so just make sure uniqID is an unsigned integer type.

Alternatively, just cast it:

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 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜