[英]Integer to byte array Little Endian and vice versa
我想要方法將整數轉換為字節數組(小端),並從字節數組(以小端方式編碼)轉換為C中的整數; 無論我們在LE還是BE機器上工作。
這些功能適合嗎?
void Int2ByteArrayLE(int x,unsigned char *byteArray)
{
byteArray[0]=x;
byteArray[1]=x>>8;
byteArray[2]=x>>16;
byteArray[3]=x>>24;
}
void ByteArrayLE2Int(unsigned char *byteArray, int*x)
{
*x=byteArray[0] | (byteArray[1]<<8) | (byteArray[2]<<16) | (byteArray[3]<<24);
}
PS。 如果x是帶符號的,這也有效嗎?
您實際上想做的是在主機字節順序和網絡字節順序之間轉換。 而您需要的是功能htonl
和ntohl
。
要將主機從網絡字節順序轉換為:
uint32_t n = (uint32_t)htonl((uint32_t)h);
而在相反的方向:
int h = (int)ntohl((uint32_t)n);
這些功能知道主機平台的字節順序。 因此,如果您在大型字節序計算機上執行代碼,則這些功能將不起作用。 但是在小端機器上,這些函數會反轉字節。
在注釋中,您暗示您的通信協議要求以小尾數字節順序傳遞信息。 這肯定是一個錯誤。 您應該遵循標准協議,並以網絡字節順序在網絡上傳輸數據。
如果您真的不能更改協議,並且希望通過電線獲得很少的字節序,則只需要一個memcpy
。 您的值已經是低位字節序,並且顯然反轉字節將無濟於事。
如果您發現自己在大型endian客戶端上使用,那么您現在當然需要反轉字節。 為此使用此功能:
uint32_t reverseBytes32(uint32_t v){
return ((v & 0xFF) << 24) | ((v & 0xFF00) << 8)
| ((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24);
}
您將需要使用強制類型轉換將帶符號的int
解釋為無符號的uint32_t
。
您的代碼有一些問題:
int
的系統上,代碼將不起作用。 因此,代碼通常是不可移植的。 您需要將代碼更改為以下內容:
#include <stdint.h>
void uint32_to_ByteArrayLE (uint32_t x, uint8_t* byteArray)
{
// explicit casts will prevent implicit conversion warnings:
byteArray[0] = (uint8_t)(x >> 0);
byteArray[1] = (uint8_t)(x >> 8);
byteArray[2] = (uint8_t)(x >> 16);
byteArray[3] = (uint8_t)(x >> 24);
}
void ByteArrayLE_to_uint32 (const uint8_t* byteArray, uint32_t* x)
{
/* casts -before- shifting are necessary to prevent integer promotion
and to make the code portable no matter integer size: */
*x = (uint32_t)byteArray[0] << 0 |
(uint32_t)byteArray[1] << 8 |
(uint32_t)byteArray[2] << 16 |
(uint32_t)byteArray[3] << 24;
}
如果不在第二個函數中進行強制轉換,則移位將發生在int
,這不是您想要的。
讓我們看一下標准(5.8 Shift運算符):
“ E1 << E2 ...,如果E1具有帶符號類型且非負值,並且E1 * 2 ^ E2在結果類型中可表示,那么它就是結果值;否則,行為是不確定的。”
“ E1 >> E2的值,E1右移E2位位置。...如果E1具有帶符號類型和負值,則結果值由實現定義。”
因此,當x帶符號且為負數時,行為對於<<而言是未定義的,而對於>>而言是實現定義的。 通常,對於帶符號的x,如果只有x為非負數,則代碼將起作用。
雅。 它也將在帶符號整數上工作,因為此代碼與MSB的>>移位無關,與MSB的符號位擴展無關。 即符號位是否置位,將不會影響代碼,因為它只涉及按原樣處理X的32位。 只需存儲並檢索32位。 因此將不考慮MSB處>>所添加的位。 要了解考慮,
如果x是int x;
//然后是帶符號整數
x = -1即11111111 11111111 11111111 11111111
的ByteArray [0] = X; 11111111 11111111 11111111 11111111
的ByteArray [1] = X >> 8; xxxxxxxx 11111111 11111111 11111111
的ByteArray [2] = X >> 16; xxxxxxxx xxxxxxxx 11111111 11111111
的ByteArray [3] = X >> 24; xxxxxxxx xxxxxxxx xxxxxxxx 11111111
>> xxxxxxxx xxxxxxxx xxxxxxxx
所添加的位不會被存儲/使用,因此不會影響代碼。
因此,由移位運算符done or not
進行符號位擴展將不會影響代碼,因為從以上示例可以清楚地看出,移位x
插入的位不用於存儲。 因此,代碼可以成功將數字存儲為binartarray中的數字,並且可以檢索回int x
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.