uint32_t快速不安全的转换为int32_t

时间:2018-06-09 12:00:43

标签: c type-conversion unsigned

我正在寻找一种快速将uint32_t转换为int32_t的方法。我可以假设所有数字都小于2 ^ 31-1,并且不需要担心代码中此时的溢出。我可以假设int32_t的符号位是uint32_t的最大位数吗?在编码方面,我可以将指向uint32_t值的指针视为指向int32_t值的指针:以下代码是否与平台无关的C代码有效并且最后一个语句是否为真? (在我的Mac上和Linux上的intel编译器都是如此)

uint32_t ui = 3;
int32_t  *i = &ui;

(int32_t)ui == *i;

2 个答案:

答案 0 :(得分:3)

如果你想要快速,并且你不关心溢出,你根本不需要做任何奇特的事情。如果你只是写

i = ui;

任何理智的编译器最多会发出一个赋值指令,尽管它可能会警告你类型不匹配和溢出的可能性。如果你写

i = (int32_t)ui;

任何理智的编译器都会发出完全相同的赋值指令,并且会吞下它对类型不匹配的怀疑(即警告你)。

没有必要涉及指针别名或类型惩罚 - 这只会使代码混淆,并可能使其不太可靠或效率低下。

如果你担心转换,以及标志位的位置,你真的不必:

  • 在二进制补码算法中,不需要转换,除非它检测溢出并抛出异常。在一个补码和符号幅度中,除非检测到溢出并抛出异常,否则不需要转换。

  • 虽然不做出与机器相关的假设是明智的,但出于所有意图和目的,您可以假设您的代码将在双补码机器上运行。 (他们非常普遍。)

  • 即使需要进行转换,无论如何都不会明显慢于直接分配。

  • 通过在C中编写一个简单的赋值(与某些指针旋转相反),您可以确保即使某些转换需要,编译器也会处理它。

答案 1 :(得分:1)

不,这不是平台无关的C代码。 C标准不需要定义int32_t也不需要uint32_t

我怀疑你实际上并不关心所有实现的平台无关C代码,我怀疑你只关心可以在你关心的平台上运行的C代码,但我不知道你在哪个实现关心。

假设存在int32_tuint32_t

使用指针转换来访问无符号类型,就好像它是相应的带符号类型一样,反之亦然,是有效的。 int32_t是与uint32_t对应的签名类型。正如@rici指出的那样,在实践中不仅如此,这是一项艰难的要求。

与此同时,这是不必要的复杂。在当前常用的平台上,从uint32_tint32_t的简单直接转换,反之亦然,没有任何指针技巧,在运行时将需要零指令并完全按照您的预期行事