[英]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_t
或uint64_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
。
但是,您的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
來0x1fe
var1
,那么它將產生0x1fe
而不是0xff000000ff
(因為在此系統上, <<32
恰好是具有32位無符號類型的無操作)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.