C++ 中的算术与逻辑移位运算

发布于 2024-12-08 13:34:05 字数 644 浏览 0 评论 0原文

我有一些代码,使用左移运算符将不同长度的参数(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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凶凌 2024-12-15 13:34:05

一般规则是逻辑移位适用于无符号二进制数,而算术移位适用于有符号 2 的比较数。这将取决于你的编译器(gcc等),而不是语言,但你可以假设编译器将对无符号数字使用逻辑移位......所以如果你有一个无符号类型,人们会认为它将是一个逻辑转移。

如果您需要编译器之间的某种可移植性,您始终可以编写自己的方法来检查并进行转换。或者您可以使用内联汇编来执行此操作并避免任何问题(但您将被固定到一个平台)。

简而言之,要 100% 正确,请检查您的编译器 doco。

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.

奶气 2024-12-15 13:34:05

这看起来像 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 

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 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文