[問題] byte跟bitset的問題

看板C_and_CPP作者 (jimmyoic)時間15年前 (2011/01/03 20:58), 編輯推噓7(7030)
留言37則, 8人參與, 最新討論串1/1
最近要寫二進位轉十進位遇到很多問題 剛開始bitwise還不怎麼會 = = 一開始我是想說 因為int是4個byte int i,mask = 0x80000000 for(i=1;i<=32;i++) { if(mask & value) printf("1"); else printf("0"); mask>>=1; if(i%8==0) // 八個bit空一個分開來比較好觀察 printf(" "); } 結果這樣輸入數字只會有2 4 8 16 等二的次方的結果(00000001 00000011 00000111..) 其他像輸入介於4~8的數字就都是輸出4的結果 輸入8~16的數字就都是輸出8的結果 然後只要一輸入128就會全部變成1111111111111111111111111111111 後來爬了一下板看到有一篇在講把一個整數的四個byte分開來存的方法 所以就想說會不會要用指標從第一個byte指到第二個byte這樣分開來 然後我又去試著去改改看 { int mask = 0x80; int i,j; char *p; p = (char*)&u.intvalue; for(i=1;i<=4;i++) { for(j=1;j<=8;j++) { if(mask & *p) printf("1"); else printf("0"); mask>>=1; } printf(" "); p++; } } 我想說分成四個byte 然後8個bit 8個bit去test 可是這樣出來的結果 譬如說我輸入8 就會變成 00001000 00000000 00000000 00000000 跟我一開始想要的 00000000 00000000 00000000 00001000 不一樣 而且如果我輸入256 就會轉成 00000000 00000000 00000000 00000000 輸入257就會跟輸入1一樣顯示00000001 00000000 00000000 00000000 我想問的是為什麼第一個方法不行 然後為什麼第二個方法裡00001000會跑到最前面 跟為什麼我這樣寫 一輸入256就會變回0 對不起敘述很爛 感謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.116.102.131

01/03 21:08, , 1F
第一種寫法,改成unsigned int i, mask = .... 就好了
01/03 21:08, 1F

01/03 21:08, , 2F
不是很清楚你想作什麼功能
01/03 21:08, 2F

01/03 21:09, , 3F
你想寫的程式是10轉2 可是內容打2轉10?
01/03 21:09, 3F

01/03 21:11, , 4F
第二種寫法,00001000在最前面是因為little endian
01/03 21:11, 4F

01/03 21:13, , 5F
而且第二種寫法,每跑完一個byte就要重設mask=0x80;
01/03 21:13, 5F

01/03 21:13, , 6F
不然到第二個byte之後,mask就一直是0了
01/03 21:13, 6F

01/03 21:15, , 7F
2轉10 不好意思我敘述很爛= =
01/03 21:15, 7F

01/03 21:18, , 8F
阿不對 10轉2拉 = ="
01/03 21:18, 8F

01/03 21:23, , 9F
第一種寫法我改成unsigned int i 還是有一樣的問題@@
01/03 21:23, 9F

01/03 21:23, , 10F
重點是 mask 必須是 unsigned
01/03 21:23, 10F

01/03 21:25, , 11F
mask改成unsigned以後就可以正確顯示256以內的2進位了
01/03 21:25, 11F

01/03 21:26, , 12F
不過一到256又會歸0 257又從00000001開始= =
01/03 21:26, 12F

01/03 21:26, , 13F
為什麼mask一定要是unsigned??
01/03 21:26, 13F

01/03 21:29, , 14F
http://nopaste.csie.org/4ca7d 這樣的257是正常的
01/03 21:29, 14F

01/03 21:38, , 15F
!!樓上j大竟猜得出那個value是什麼,我剛還一直在猜說
01/03 21:38, 15F

01/03 21:39, , 16F
不過另一個u.intvalue;我就猜不透了 XD
01/03 21:39, 16F

01/03 21:39, , 17F
if(mask & value) ----> 莫名多出來的 value...
01/03 21:39, 17F

01/03 21:47, , 18F
阿對不起 = = 因為我原本是在union裡宣告的 intvalue
01/03 21:47, 18F

01/03 21:50, , 19F
完全沒注意到忘記改= =
01/03 21:50, 19F

01/03 21:53, , 20F
謝謝樓上熱心回答! 雖然還是不知道為什麼要加unsigned
01/03 21:53, 20F

01/03 21:57, , 21F
去查一下 >> 這個shift operator使用時的注意事項....
01/03 21:57, 21F

01/03 21:58, , 22F
簡單的說, 有號數的MSB(或者視為sign bit)是1時, >> 的
01/03 21:58, 22F

01/03 21:59, , 23F
結果, 與無號數(unsigned)的MSB為1時>>的結果並不同.
01/03 21:59, 23F

01/03 22:00, , 24F
MSB: 最高位的意思. 或者你會用union的話, 試試把一個
01/03 22:00, 24F

01/03 22:01, , 25F
int與一個unsigned int union在一起, 然後試試看假設給
01/03 22:01, 25F

01/03 22:02, , 26F
uint那個初值為0x88FF0000, 之後分別觀察用int那個去>>
01/03 22:02, 26F

01/03 22:02, , 27F
的結果, 與用uint那個element去>>的結果有何不同:)
01/03 22:02, 27F

01/03 22:26, , 28F
Primer 4e p155,運算元若為signed,用shift取決於編譯器
01/03 22:26, 28F

01/03 22:29, , 29F
(驚) 糟糕, 小弟一直以為signed的case是補MSB....Orz
01/03 22:29, 29F

01/03 22:37, , 30F
所以保險的方式還是自己去處理 signed bit.
01/03 22:37, 30F

01/03 23:22, , 31F
我也記得是用 signed shift...
01/03 23:22, 31F

01/03 23:23, , 32F
大概是為了只有 logical shift 的環境吧 (我猜)
01/03 23:23, 32F

01/03 23:27, , 33F
@_@
01/03 23:27, 33F

01/05 00:36, , 34F
啊我知道為什麼了 因為標準沒規定負數的表示法得是二補數..
01/05 00:36, 34F

01/05 00:40, , 35F
推樓上 L 大..
01/05 00:40, 35F

01/05 01:50, , 36F
LPH整個很威啊!!學長好XD
01/05 01:50, 36F

01/05 23:49, , 37F
糟糕~~小弟我完全把二補數當作必然了....Orz
01/05 23:49, 37F
文章代碼(AID): #1D8SVVj6 (C_and_CPP)