2016-10-11 106 views
2

我有以下UINT8變量:如何將4個UINT8變量連接成一個UINT32變量?

UINT8 var1 = 0b00000001; //0000 0001 
UINT8 var2 = 0b00000011; //0000 0011 
UINT8 var3 = 0b00000111; //0000 0111 
UINT8 var4 = 0b00001111; //0000 1111 

我想這四個UINT8變量打包成一個UINT32變量具有以下值:

UINT32 var1 = 0b00000001000000110000011100001111; //00000001 00000011 00000111 00001111 

請問下面的代碼正確,安全地做到這一點?

UINT32 var1 = (var1<<24) + (var2<<16) + (var3<<8) + var4; 
+1

好的,對於這個我們確實需要知道底層類型。但它很可能被破壞。 –

+0

@BaummitAugen你是什麼意思的基礎類型?我將字節值存儲在變量中。那是你所指的? –

+4

您似乎認爲'00000001'等是二進制文字。你正在使用哪種C++編譯器? – Michael

回答

6

簡短回答,

我不會擔心你編寫二進制數字的方式。我會在十六進制輸入它們,讓你通過這有關的SO問題尋找二進制表示:Can I use a binary literal in C or C++?

#include "stdafx.h" // you are using devstudio 
#include <Windows.h> // you are using windows types 
#include <iostream> // I print out the result 
#include <bitset>  // I use bitset to print the binary string 

int main() 
{ 
    UINT8 var1 = 0x01; //0000 0001 
    UINT8 var2 = 0x03; //0000 0011 
    UINT8 var3 = 0x07; //0000 0111 
    UINT8 var4 = 0x0F; //0000 1111 

    UINT32 bigvar = (var1 << 24) + (var2 << 16) + (var3 << 8) + var4; 
    std::cout << std::bitset<32>(bigvar) << std::endl; 
} 

你的數學是正確的和安全的。字節是獨立聲明的,所以你不必擔心字節順序。這些類型都是無符號的,所以沒有符號位的UB問題。這些轉換都適合正確的位數,所以不會溢出。我生成:

00000001000000110000011100001111 

或者,可以在一個32位整數已讀爲4個字節,並且重建的32位數字,但不會是便攜式的,因爲有時號碼存儲順序相反。例如,在TIFF中,您可以讀取一個標題值,告訴您是否將var1放在第一位並向上計數,或者先將var4放倒並倒計數。字節順序是幾乎所有將大量字節組合成更大整數類型的實際應用中需要注意的。查看big-endian和little-endian以獲取更多信息。

+4

*「你的數學是正確和安全的。」*不,它不是。 var1 << 24'可能是UB。 –

+1

我將不得不考慮這一點。我的生產代碼與tiff操作庫中的類似。它何時會失敗? –

+2

它通過移動到符號位(在您的平臺上給定「int」是32位)來調用所有'var1> 127'的UB。 –

相關問題