【问题标题】:Bit manipulation and > 32 bit numbers?位操作和> 32位数字?
【发布时间】:2014-01-19 02:28:12
【问题描述】:

我基本上是在尝试做以下事情:

c[i] = ((number_to_store << pos) & 0xFF00000000) >> 32;

但这会将0 存储在c[i] 中,这不是预期的。下面的工作就像一个魅力:

c[i] = ((number_to_store << pos) & 0xFF000000) >> 24;

我 99% 确定该错误与我的所有变量都是 unsigned int 的事实有关,但这里我请求 40 位空间。

有人可以解释小于或等于32位大于32位数字之间的区别,当它是关于位操作时?

编辑:这也给了我 0:

cout << ((((unsigned long)number_to_store << (unsigned long)pos) & (unsigned long)0xFF00000000) >> 32) << endl;

编辑2:以下作品:

cout << ((((unsigned long long)number_to_store << (unsigned long long)pos) & (unsigned long long)0xFF00000000) >> 32) << endl;

经验教训:永远不要期望 long 大于 int

【问题讨论】:

  • 没有什么不同,你只是有更多的空间来处理。
  • 有什么理由在0xFF00000000末尾加上UL
  • 当心在某些尺寸下使用轮班而不是分隔...在某些平台上是undefined behavior。最值得注意的是,如果您使用 int 移动超过 31 位,x86 和 x86-64 会做一些奇怪的事情。
  • 感谢您指出这一点,您能解释一下吗?
  • @Luka 基本上使用 32 位 int,移动超过 31 位是未定义的行为。使用 64 位类型,移动超过 63 位是 UB。所以c[i] 应该是long long 类型才能安全地移动32位。

标签: c++


【解决方案1】:

unsigned int 是 32 位,如果将它移动 32 位,它将变为 0。正如您所发现的,为了保留在第一次移位中左移的位,您必须将 number_to_store 声明为 @ 987654323@,即 64 位。

【讨论】:

  • 如果在 msvc 上是 4 个字节,而 int 也是 4 个字节,为什么 long 存在?为什么他们试图迷惑人?
  • 编译器定义为标准没有定义整数类型的大小。这个问题可能会阐明为什么 MSVC 将 int 定义为与 long 相同的大小:stackoverflow.com/questions/18353168/…
  • @EricFortin 它不一定会归零,请参阅我对上述问题的评论中指向拉里奥斯特曼博客的链接。在 32 位类型上移动超过 31 位是未定义的行为。
猜你喜欢
  • 2013-10-31
  • 2020-09-12
  • 2015-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多