繁体   English   中英

将2个uint16_t合并为1个uint32_t

[英]Combining 2 uint16_t into into 1 uint32_t

我有2个uint16_t,我想组合成1个32位数字:

uint16_t var1 = 255; // 0000 0000 1111 1111
uint16_t var2 = 255; // 0000 0000 1111 1111

uint32_t var3 = (var1 << 16) +  var2;

我希望var3为0000 0000 1111 1111 0000 0000 1111 1111 ...所以十进制16711935但我得到255(0000 0000 0000 0000 0000 0000 1111 1111)。

有任何想法吗?

谢谢

当对整数类型进行移位时,两个操作数都将首先提升,并且所得整数与提升后的左操作数具有相同的类型。

编译器将首先尝试将uint16_t提升为int ,如果一个int无法保存该值(即,该值大于INT_MAX),它将被提升为unsigned int 现在,如果您的系统使用16-bit int ,结果仍将是16位,因此只要您的shift值小于16,就将丢失左移情况下的最高有效位。未按标准定义。

在这种系统中,您需要首先转换为更宽泛的整数类型(例如uint32_tuint64_t ,然后左移。 为了安全起见,我们总是可以将移位的左操作数强制转换为期望的type以使我们的代码不受编译器设计者做出的实现决定(如位宽)的影响。

在某种程度上,这取决于平台。 在我最近的系统上,我们得到了预期的结果,可以通过一个简短的程序进行演示:

#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>

int main()
{
    uint16_t var1 = 255; // 0000 0000 1111 1111
    uint16_t var2 = 255; // 0000 0000 1111 1111

    uint32_t var3 = (var1 << 16) +  var2;

    printf("%#"PRIx32"\n", var3);
}

输出为0xff00ff

但是,您的var1var2在进行任何算术运算之前都会经过普通的整数提升 如您所见,如果提升的类型不能保存中间结果,则部分计算可能会丢失。

您可以通过在算法前显式扩展var1来避免此问题:

    uint32_t var3 = ((uint32_t)var1 << 16) +  var2;

我的系统上等效的失败程序是:

#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>

int main()
{
    uint16_t var1 = 255; // 00ff
    uint16_t var2 = 255; // 00ff

    uint64_t var3 = ((uint64_t)var1 << 32) +  var2;

    printf("%#"PRIx64"\n", var3);
}

如果我不按所示使用演员0x1fe0x1fe var1 ,那么它将产生0x1fe而不是0xff000000ff (因为在此系统上, <<32恰好是具有32位无符号类型的无操作)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM