为什么我不能将这些内容整理在一起?
问题描述:
我有以下代码。我们的目标是将两个uint32_t
小号组合成一个单一的uint64_t
,然后检索值。为什么我不能将这些内容整理在一起?
#include <iostream>
#include <cstdint>
int main()
{
uint32_t first = 5;
uint32_t second = 6;
uint64_t combined = (first << 32) | second;
uint32_t firstR = combined >> 32;
uint32_t secondR = combined & 0xffffffff;
std::cout << "F: " << firstR << " S: " << secondR << std::endl;
}
它输出
F: 0 S: 7
如何成功找回正确的价值观?
答
当执行first << 32
,你正在转移32位的32位的空间内,所以有移位后剩余的位。移位的结果是0。你需要将first
值转换为64位,你可以快步前:
uint64_t combined = (uint64_t(first) << 32) | second;
答
first
是一个32位的类型和由32位你位移位它。这在技术上是未定义的行为,但可能最可能的结果是该表达式的结果为0.您需要在对它进行位移之前将其转换为更大的类型。
uint64_t combined = (static_cast<uint64_t>(first) << 32) | second;
+0
Upvoting此答案而不是其余两个,因为使用'static_cast '而不是C风格的强制转换 – Fureeish
答
按照评论:
#include <iostream>
#include <cstdint>
int main()
{
uint32_t first = 5;
uint32_t second = 6;
uint64_t combined = (uint64_t(first) << 32) | second;
uint32_t firstR = combined >> 32;
uint32_t secondR = combined & 0xffffffff;
std::cout << "F: " << firstR << " S: " << secondR << std::endl;
}
位处理运算符返回一个类型的第一个参数。所以,你需要将其转换为uint64_t
,以便它有余地second
值。
你应该尝试使用一个编译器,它自己检测你的编程错误,并且责骂你:'warning:left shift count> = type [-Wshift-count-overflow]'的宽度'。当然,这将是gcc。你的'int'是32位,因此你的左移操作在32位值上运行,并溢出。在移动之前,将'first'明确地强制转换为'uint64_t'。然后切换到gcc,这是整个宇宙中最好的编译器,而不仅仅是这个世界。 –