代码之家  ›  专栏  ›  技术社区  ›  moonraker

将2个uint16\u t合并为1个uint32\u t

  •  0
  • moonraker  · 技术社区  · 9 年前

    我有两个uint16\t,我想合并成一个32位数字:

    uint16_t var1 = 255; // 0000 0000 1111 1111
    uint16_t var2 = 255; // 0000 0000 1111 1111
    
    uint32_t var3 = (var1 << 16) +  var2;
    

    有什么想法吗?

    谢谢

    2 回复  |  直到 9 年前
        1
  •  3
  •   m0h4mm4d    9 年前

    当整数类型被移位时,两个操作数首先被提升,得到的整数具有相同类型的提升左操作数。

    uint16_t int 整数 无法保存该值(即该值大于INT_MAX),它将被提升为 unsigned int .现在如果您的系统使用 16-bit int

    uint32_t uint64_t 然后左移。为了安全起见,我们总是可以将移位的左操作数转换为预期的 type 因此,我们的代码不受编译器设计器所做的实现决策(如位宽度)的影响。

        2
  •  2
  •   Toby Speight    9 年前

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

    #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 .

    然而,您的 var1 var2 经历 正常整数促销

    可以通过显式加宽来避免问题 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);
    }
    

    这会产生 0x1fe 0xff000000ff var1 <<32 恰好是32位无符号类型的no op)。