【问题标题】:math operation between 2 uint32_t returning an uint64_t2 uint32_t 之间的数学运算返回一个 uint64_t
【发布时间】:2013-11-28 15:17:42
【问题描述】:

我正在尝试使用类似 uint64_t foo(uint32_t,uint32_t) 这样的接口来实现一个操作、一个函数,所以这是一个简单的实现:

#include <iostream>
#include <cstdint> 

uint64_t foo(const uint32_t &a, const uint32_t &b) {    
  return ((reinterpret_cast<const uint64_t &>(a)) +
          (reinterpret_cast<const uint64_t &>(b)));
}

int main() {
  uint32_t k1 = ~0;
  uint32_t k2 = 1;
  std::cout << foo(k1, k2) << "\n";
  return (0);
}

现在我的重点是reinterpret_cast+ 运算符。

+ 运算符应该没问题,因为它被 2 uint64_t 调用;所以问题是reinterpret_cast?我不明白为什么... 我的猜测是关于ab 附近的内存块,所以reinterpret_cast 的结果是原始ab 的50%,另外50% 是随机块的记忆。我这就是这个演员阵容的真正运作方式?

我已经尝试了 reinterpret_cast 的多个版本,即使使用指针,也没有运气。

【问题讨论】:

    标签: c++ unsigned-integer


    【解决方案1】:

    reinterpret_cast 本质上是告诉编译器忽略它的所有类型安全,只接受你正在做的事情。

    您是说您的引用不是对 32 位数字的引用,而是对 64 位数字的引用。这当然意味着(在每字节 8 位的系统中),可能包含任何数据的 4 个字节被读取为整数的一部分。您还有一个与大端系统相关的“可移植性”问题,特别是在更重要的字节首先出现的情况下,因此即使其他字节恰好为零,也会产生不同的数字。

    您执行此操作的正确方法是static_cast,而不是使用引用而是“按值传递”。

    事实上,您可以设法编写 foo 而无需任何强制转换。

    uint64_t foo( uint64_t a, uint64_t b ) { return a + b; }
    

    您可以使用 32 位数字调用它,而不必担心它们是否溢出。 (尝试将它们相乘)。

    【讨论】:

    • reinterpret_cast 对我来说最有趣的部分是它基本上是一个无条件强制转换,所以几乎没有开销,没有办法保留和清除下一块内存什么时候做演员?
    • 不,因为那块内存可能已经分配给别的东西了。即使有可能,它也会引入比简单地在堆栈上创建另一个变量更高的开销。
    • @user2485710:隐式转换和static_cast 也没有运行时开销,只是编译时检查。 reinterpret_cast 摆脱了编译时检查,允许进行各种奇怪而奇妙的转换,无论它们是否有意义。您可能会想出一些可怕的方法来保留空间并使引用转换“起作用”,但它可能不如简单、安全的值转换有效。
    • @MikeSeymour 我实际上正在考虑使用 32 位类型和 64 位类型作为填充符的 union。但我认为我会使用static_cast
    【解决方案2】:

    你太努力了。按值传递并使用static_cast。此外,请使用uint_least32_tuint_fast32_t,以更合适的为准,而不是坚持可能不存在的确切大小。

    【讨论】:

    • static_cast 的开销是多少?
    • @user2485710:编译时检查。没有运行时开销(除了转换本身,您在任何情况下都需要)。
    • @MikeSeymour 如果检查发生在编译时,那么当我在运行时传递我的值时会发生什么?
    • @user2485710:这取决于平台和调用约定。在 64 位平台上,可能没有成本 - 只需将 32 位值放入 64 位寄存器可能会做正确的事情。在 32 位(或更小)平台上,它可能会将值写入堆栈(或写入寄存器),并在其旁边写入零值(或写入第二个寄存器)。不管它做什么,它将是执行转换的最快方法,除非编译器被无可救药地破坏了。
    • @user2485710 - 开销在于,与 reinterpret_cast 不同,它可以满足您的需求。
    猜你喜欢
    • 2019-07-23
    • 2016-07-22
    • 2020-03-09
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 2023-04-01
    相关资源
    最近更新 更多