C++:将 unsigned long long 转换为 unsigned long

C++: convert unsigned long long to unsigned long

我正在尝试将 unsigned long long 转换为 unsigned long。以下是正确的做法吗?

unsigned long removeExtraBits2(unsigned long long c) {
    return (unsigned long) ((c << 32) >> 32);
}

如果没有,能否提供一个工作示例?

我的假设是当左移然后右移时,最左边的 32 位设置为 0。

谢谢!

编辑:转换的目的是去除多余的位,'higher' 比第 32 位,有效地只将最右边的 32 位保留为无符号长。

只需执行 "plain" 转换((unsigned long)c,或者,如果您喜欢冗长,static_cast<unsigned long>(c),甚至只需将 unsigned long long 源值分配给 unsigned long 目标变量),标准保证左边的额外位将被截断。

If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type).

(C++11, §4.7 ¶2)

如果源是无符号的(或者是有符号的并且在 2 的补码算法中),这是一种奇特的方式来表示额外的位被截断了。

有许多不同的处理器和操作系统。 unsigned long long 几乎所有东西都是 64 位的。 unsigned long 是另一回事。例如,64-bits on Linux x86-64,32-bits on Linux x86-32 and在 Windows x86-64 和 x86-32 上 32 位。普通转换可能是空的。

我认为这是一个安全的解决方案。

unsigned long removeExtraBits(unsigned long long c) {
    c %= 0x100000000ULL;
    return (unsigned long)(c);
}

编译器会将 % 更改为简单的 mov