[問題] union / struct 表示 double 位元

看板C_and_CPP作者 (藍影)時間14年前 (2011/04/16 03:52), 編輯推噓7(7014)
留言21則, 9人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) vc2008 問題(Question): 我先用 struct 定義出 ieee754 欄位, 接著在 union 放入 struct 與 double, 當設定 union 之 double 後,是否就能觀察出 ieee754 各欄位數值? 但出來的結果,與 http://www.h-schmidt.net/FloatApplet/IEEE754.html 相對照,結果並不相同,非如我所預期 程式碼(Code):(請善用置底文網頁, 記得排版) #include <stdio.h> typedef struct tagIEEE754{ unsigned char Signed:1; unsigned short Exp:11 unsigned long long Mantissa:52; }IEEE754; typedef union tagfFormat { IEEE754 i754; double floating; }fFormat; int main() { double x=-12345.6789; fFormat f = {0}; f.floating = x; printf("floating:%lf\n", f.floating); printf("signed:%hhx mantissa:%hx exp:%llu\n", f.i754.Signed,f.i754.Mantissa, f.i754.Exp); return 0; } 補充說明(Supplement): 我只是好奇有沒有辦法針對浮點數某個 bits 做設定 我試著做這個動作 #define DBL_BITS (sizeof(double)) #define DBL_EXP_DIG (DBL_BITS - DBL_DIG - DBL_MANT_DIG ) double x = 123456.789; Signed = ((unsigned long long)x) & (0x1ULL << (DBL_BITS -1)) >> ( DBL_BITS-1); printf("%llu\n", Signed); 結果 x 不論為正為負,Signed 都是 1,出現以下 warnning <<' : 移位計數為負值或太大,未定義的行為 或是 floating 就不能用 bitwise ? 謝謝各位指正。 -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.73.222

04/16 04:05, , 1F
double 不是 1-11-52 嗎? :)
04/16 04:05, 1F
謝謝指正 :)

04/16 04:12, , 2F
單回你 floating 是否能用 bitwise. 答案是否定的
04/16 04:12, 2F

04/16 04:13, , 3F
但是你可透過 int pointer type 來對其作 bitwise
04/16 04:13, 3F

04/16 04:32, , 4F
(unsigned long long)x 這樣會做轉型吧? 1.9 變 1
04/16 04:32, 4F

04/16 04:57, , 5F
這樣應該可以吧? http://ppt.cc/MfOV 沒有 stdint.h
04/16 04:57, 5F

04/16 04:57, , 6F
的話 windows.h 應該可以找一下
04/16 04:57, 6F
這樣的確可行,MSCV 下的 stdint.h 找了一下,發現這裡有 http://msinttypes.googlecode.com/svn/trunk/stdint.h http://www.azillionmonkeys.com/qed/pstdint.h 這二版都可以正常跑 (目前用沒什麼問題)

04/16 06:19, , 7F
版主都不用睡覺的 o_O
04/16 06:19, 7F

04/16 11:10, , 8F
f = (unsigned long long) x; 是 cast, 要亂搞的話應該要
04/16 11:10, 8F

04/16 11:10, , 9F
unsigned long long *i = (unsigned long long *)&x;
04/16 11:10, 9F
寫久了頭都暈了, 謝謝 mking19880326, purpose, ledia 指出 不用 union 拿 loveme00835 給的來改的確也可行 http://codepad.org/P6rC8o9Z

04/16 11:34, , 10F
你的IEEE754不能這樣定義吧?? 這樣定義sign會整個佔掉
04/16 11:34, 10F

04/16 11:35, , 11F
一個整個char(雖然只用其1 bit). 再加上align, 小弟用
04/16 11:35, 11F

04/16 11:35, , 12F
VC2008 sizeof它足足有16 bytes; 要的話bitfield應該是
04/16 11:35, 12F

04/16 11:36, , 13F
從第一個到最後一都用unsigned long long宣告吧@_@"
04/16 11:36, 13F

04/16 11:41, , 14F
糟, 小弟sizeof(ull)也是4byte.Orz 直接__int64才行Orz
04/16 11:41, 14F

04/16 11:46, , 15F
測了一下, 用ull就算32bit也沒關係, 別更換型態就好:)
04/16 11:46, 15F
的確,昨晚忽視了 alignment 問題,謝謝指正。

04/16 12:01, , 16F
咦 long long 不是跟double一樣大嗎?
04/16 12:01, 16F

04/16 12:02, , 17F
可能是比較早的 compiler 認不得 long long 當它是 long 吧
04/16 12:02, 17F

04/16 12:02, , 18F
印象中 VC6 就認不得 long long
04/16 12:02, 18F
的確,VC6 只能用 __int64 / unsigned __int64 , long long 宣告應是 error 同時 cout / cin 這二支都沒 overloading, 也是我考慮拋棄 vc6 的第一個原因!

04/16 12:33, , 19F
你的 IEEE754 的 struct 是不是寫相反了 ...
04/16 12:33, 19F
真的!已修正, 謝謝指正! Mantissa / Exp 寫反

04/16 14:32, , 20F
一個要考慮的事情是 bit field 雖然你 bit 數有數對
04/16 14:32, 20F

04/16 14:33, , 21F
但是整個結構的大小可能過大導致沒有對齊好
04/16 14:33, 21F
的確有漏考慮,謝謝 loveme00835 熱心指導與說明! ※ 編輯: tropical72 來自: 180.177.73.222 (04/16 15:02)
文章代碼(AID): #1DgA8Dn5 (C_and_CPP)