簡體   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