[問題] printf 格式不同問題(修正)

作者: hpyhacking (駭人聽聞)   2017-10-27 02:29:16
開發平台(Platform): (Ex: Win10, Linux, ...)
win 10 用cygwin64
64位元
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
GCC
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
no
問題(Question):
簡單的printf問題
int a = 10;
printf( "%f\n", a );
float w = 35.14;
printf( "%w d\n", w );
餵入的資料(Input):
沒有
預期的正確結果(Expected Output):
預期第一個printf輸出的是10.0
當然結果大家知道是0
想請問為甚麼這個型態錯誤印出的是0 ?
原本想說都是佔4bytes應該會誤打誤撞可以顯示好
爬到英文說跟甚麼IEEE有關?英文看不是很懂....
再來既然格式都一樣錯誤
為甚麼第二個printf有印出東西但是是亂數,這個數是其他記憶體空間裡的數字嗎?
錯誤結果(Wrong Output):
0 ( undefined? )
1073741824 ( 亂數 )
程式碼(Code):(請善用置底文網頁, 記得排版)
補充說明(Supplement):
作者: LPH66 (-6.2598534e+18f)   2017-10-27 02:34:00
這問題會牽涉到不少這些 C 語言功能的實作細節要完整回答會很長一串, 但一般寫程式不需要考慮這些細節
作者: kingofsdtw (不能閒下來!!)   2017-10-27 02:35:00
google吧 :D
作者: Schottky (順風相送)   2017-10-27 02:41:00
我覺得不好,我覺得這樣寫程式很危險,把 -Wall 打開吧
作者: hpyhacking (駭人聽聞)   2017-10-27 02:44:00
這是故意的
作者: a58524andy (a58524andy)   2017-10-27 06:00:00
先讀計概
作者: peterwu4 (notd)   2017-10-27 07:42:00
可以查一下float和int儲存格式的差異~ 啊,你已經查了XD找中文的網頁說明來看~
作者: vm0 (....)   2017-10-27 10:17:00
我實際在linux上用gcc跑,printf("%d\n",w)會是35,跟印象中一樣,在宣告時就會自動省略小數,請教是為什麼呢?
作者: nh60211as   2017-10-27 10:22:00
他要打double w = 35.14打錯了吧
作者: vm0 (....)   2017-10-27 10:41:00
原來如此,看前幾樓回的還以為我哪裡搞錯了,謝謝
作者: nh60211as   2017-10-27 10:56:00
我也不確定,照他的錯誤結果輸入應該是浮點數才對
作者: MOONRAKER (㊣牛鶴鰻毛人)   2017-10-27 11:08:00
printf不依照格式字串檢查變數格式。有錯誤結果自負。
作者: hpyhacking (駭人聽聞)   2017-10-27 12:07:00
先謝謝大家一聲,還有我現在就是在讀計概QQ不好意思有打錯的!!!
作者: Schottky (順風相送)   2017-10-27 13:38:00
假如 printf 期望的 size 和變數 size 不一樣會出大事
作者: ersfw4418 (隱身術)   2017-10-27 16:47:00
IEEE754
作者: yvb   2017-10-27 20:42:00
若是要 "正確的" 把 double "誤" 當做 int 來印, 應該寫做printf("%d\n", *(int *)&w); 結果 35.14 會是 -2061584302而原 PO 的 printf("%d\n", w); 在 Linux 系統開了 ASLR 時,甚至每次顯示結果都不同, 真的像是亂數一般. 顯然是 va_list這個黑盒子中不知發生了什麼事.
作者: akasan (KITO)   2017-10-27 20:48:00
ABI
作者: AstralBrain   2017-10-27 21:30:00
以 amd64 來說, 浮點數 w 會進 xmm0 register然後 printf 從沒使用的 rdi 讀一個整數, 所以是什麼值都有可能
作者: PkmX (阿貓)   2017-10-28 15:45:00
樓上rdi應該是format string 所以下一個參數是rsi
作者: AstralBrain   2017-10-29 06:08:00
啊對... 忘了有 format string
作者: LPH66 (-6.2598534e+18f)   2017-10-29 09:13:00
這裡還要考慮可變參數, 我其實不太確定 amd64 的可變參數會不會用到浮點數暫存器...我所知的可變參數實作幾乎都是全部推堆疊噢, 找到資料了, 即使是可變參數 amd64 一樣會用暫存器那用了多少 xmm 暫存器傳浮點數會以 al 傳進去所以就是上面 Astral 講的那個樣子
作者: yvb   2017-10-30 00:46:00
其實我前面只是要指出, 原PO 的問題, 在 X86-64 的環境下,並非單純是 IEEE754 的問題, 照規則算出 "亂數" 會不符合;當然, 若是在 i386 (32-bit) 的環境, 應該就會回歸單純了.另外, 上面 regs 的推論, 會讓人覺得在瞎子摸象, 可參考(1) http://goo.gl/yP27aR 及 (2) http://goo.gl/WPLhd9此外, 依據 (1) 及其後 List 的 X86-64 段落, 我的測試使用Linux => System V AMD64 ABI, 但原PO 則為 Win10 cygwin64,不知是會採用 SysV 還是 M$ X64 calling convention ?有關 regs 的相關推論, 不知是否依舊完全符合?
作者: hpyhacking (駭人聽聞)   2017-11-10 17:53:00
今天期中考完我再來研究一下

Links booklink

Contact Us: admin [ a t ] ucptt.com