[問題] 處理一個256-bit message的內容

看板C_and_CPP (C/C++)作者 (心誠則靈)時間15年前 (2010/08/15 20:59), 編輯推噓4(4026)
留言30則, 5人參與, 最新討論串1/1
開發平台:VC++ 2005 問 題:處理一個 256-bit message,以下說明簡化成處理 72 bits 目 的:得到message的內容,如 (MSB是最小bit) bit 1~8 : 名稱a1,值為unsigned int. bit 9~14 : 名稱a2,值為unsigned int. bit 15~18: 名稱a3,值為unsigned int. bit 19~30: 名稱a4,值為signed int. bit 31~42: 名稱a5,值為signed int. bit 43~54: 名稱a6,值為signed int. bit 55~66: 名稱a7,值為signed int. bit 67~72: empty 目前作法:建立一個union union U1{ struct message m; char data[9];}; 其中 struct message{ int empty:6; int a7:12; int a6:12; int a5L:2; //bit 72~41 int a5H:10; int a4:12; int a3:4; int a2:6; //bit 40~9 unsigned char a1; //bit 8~1 }; 遇到問題:可以順利得到a6,a7的值, 但12-bit a5被切割成兩部分,還要經過處理才能得到值 a3,a2則是被受限成signed int. 範 例://以winsock.h中的recv()函式所接收到的字元陣列 //buf[0]:bit 1~8 以此類推 char buf[9]={0xC6,0x0D,0x2A,0xAA,0xAA,0xAA,0xA8,0x05,0x6A}; //因應記憶體儲存字元陣列順序,將原始陣列反向 char BUF[9]={0x6A,0x05,0xA8,0xAA,0xAA,0xAA,0x2A,0x0D,0xC6}; U1 u; memcpy(u.data,BUF,9); printf("a7=%d\n",u.m.a7); 請問各位,是否有方法可避免a5被切成兩部分,而可以直接得到值 還有a3,a2被限制住的問題。 我先前有試過利用>>與&運算子,但處理12-bit 成signed int.很繁複 還是說我一開始處理的方式就不對,大家都如何parse收到的封包資料呢?! 謝謝!! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.123.129.39

08/15 21:23, , 1F
你能改封包格式嗎?
08/15 21:23, 1F

08/15 21:31, , 2F
沒辦法...
08/15 21:31, 2F

08/15 21:45, , 3F
以buf[9]當輸入的話 可以把a1~a7的值用人工算出來嗎
08/15 21:45, 3F

08/15 21:46, , 4F
想核對一下 XD
08/15 21:46, 4F

08/15 21:54, , 5F
a1=198, a2=3, a3=4, a4=a5=a6=-1366, a1=21
08/15 21:54, 5F

08/15 22:00, , 6F
a1=198, a2=3, a3=4, a4=a5=a6=-1366, a7=21 更正
08/15 22:00, 6F

08/15 22:06, , 7F
用範例印出a2, a3值會是正確,不過這是因為剛好它們都是正數
08/15 22:06, 7F

08/15 22:26, , 8F
我不懂 a2 a3 被限制的問題..
08/15 22:26, 8F

08/15 22:48, , 9F
回Y大: 因為a2,a3格式是unsigned,但在struct裡是宣告成signed
08/15 22:48, 9F

08/15 22:48, , 10F
所以若a2, a3 MSB為1,printf出來會是負數
08/15 22:48, 10F

08/15 22:48, , 11F
其實struct bit 40~9中,可以改宣告成其他資料型態
08/15 22:48, 11F

08/15 22:49, , 12F
不過這樣就會有被切割的問題,謝謝大家!
08/15 22:49, 12F

08/15 22:53, , 13F
那位何不乾脆都宣告成unsigned?
08/15 22:53, 13F

08/15 23:08, , 14F
我的意思就是你幹嘛不宣告成 unsigned XD
08/15 23:08, 14F

08/15 23:10, , 15F
且如果你要 printf unsinged 的時候應該用 %u
08/15 23:10, 15F

08/15 23:20, , 16F
unsigned 才是 位元操作 的王道阿 wwwww
08/15 23:20, 16F

08/15 23:29, , 17F
宣告成signed是因為a4為有號數,不過利用%u這樣a2,a3的問題
08/15 23:29, 17F

08/15 23:29, , 18F
就解決了!!
08/15 23:29, 18F

08/15 23:38, , 19F
a4有號跟a2a3有什麼關係..?
08/15 23:38, 19F

08/16 00:04, , 20F
搞錯,a2,a3還是沒有解決@@ 有什麼方法能讓a4印出有號,
08/16 00:04, 20F

08/16 00:04, , 21F
但a2, a3是無號嗎?!
08/16 00:04, 21F

08/16 08:43, , 22F
有號數有這麼複雜嗎???? 看一下spec就好了,用C寫很容易
08/16 08:43, 22F

08/16 20:07, , 23F
感謝各位的建議,另外a5被切割的問題,有解決辦法嗎?!
08/16 20:07, 23F

08/17 00:07, , 24F
經過實驗 每32bit 會重新對齊一次
08/17 00:07, 24F

08/17 01:11, , 25F
沒辦法解決,因為 byte padding 本來就是實作決定..
08/17 01:11, 25F

08/17 01:12, , 26F
可能A編譯器4byte, B編譯器8byte, C編譯器根本不padding
08/17 01:12, 26F

08/17 01:13, , 27F
基本上 bit field 連 bit order 都是實作決定了..
08/17 01:13, 27F

08/17 01:13, , 28F
根本就沒有 portable 的方法,你作好的解法就是寫個函數去
08/17 01:13, 28F

08/17 01:13, , 29F
手動把兩邊的 bits 合起來,很簡單好嗎?不用兩行...
08/17 01:13, 29F

08/17 12:16, , 30F
文章代碼(AID): #1CP-Izds (C_and_CPP)
文章代碼(AID): #1CP-Izds (C_and_CPP)