【问题标题】:C++: convert unsigned long long to unsigned longC++:将 unsigned long long 转换为 unsigned long
【发布时间】:2015-04-21 22:28:50
【问题描述】:

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

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

如果没有,你能提供一个可行的例子吗?

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

谢谢!

编辑:转换的目的是去除多余的位,“高于”第 32 位,有效地将最右边的 32 位保留为无符号长整数。

【问题讨论】:

  • static_cast&lt;unsigned long&gt;(c); 不够好?你为什么要写一个函数?
  • 你从哪里得到“32”?如果unsigned long 有 64 位呢?还是49?还是 111?
  • 因为它似乎不起作用。我有unsigned long long c = 39134856588429;在执行unsigned long converted = (unsigned long) c; 时,我得到 3409554573,这显然是不正确的
  • @Dimebag, Why not?或者如果你更喜欢masking...
  • 哎呀,你是对的。现在这很尴尬......编码太多,甚至无法正确思考

标签: c++ unsigned


【解决方案1】:

只需执行“普通”转换((unsigned long)c,或者,如果您喜欢冗长,static_cast&lt;unsigned long&gt;(c),或者甚至只是将 unsigned long long 源值分配给 unsigned long 目标变量),标准保证左侧的多余位将被截断。

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2n 其中 n 是用于表示无符号类型的位数)。

(C++11,§4.7 ¶2)

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

【讨论】:

  • 我认为没有无符号溢出这样的事情。它只是规定值,而不是溢出:如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2ⁿ 其中 n 是用于表示无符号类型的位数) i> 当然还是一样的答案。
  • 但是,如果您需要放弃除低 32 位之外的所有位,请不要使用 unsigned long,使用 uint32_t
  • @chris:你说得对,我不知道我记得什么;甚至还有一条注释说“这意味着无符号算术不会溢出”。
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    • 2016-04-19
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多