作者jokingfish (ㄚ魚!!)
看板C_and_CPP
標題Re: [問題] 請問0.0 和-0.0
時間Thu Nov 8 14:04:27 2012
想回的有點多 請恕我另外開一篇回應
: 餵入的資料(Input):
: 輸入數值為 0
:
: 預期的正確結果(Expected Output):
: -0.0 (我的電腦)
:
: 錯誤結果(Wrong Output):
: 0.0 (客戶的電腦)
:
: 程式碼(Code):(請善用置底文網頁, 記得排版)
: double b;
: file >> b;
: float a = -(float) b;
: printf("%f",a);
:
: CString score;
: score.Format("%2.2f",a);
: if(score == "0.00")
: 補充說明(Supplement):
: 以上是我簡化程式碼後的結果
: 從出錯的地方 和客戶電腦交叉比對後 才發現問題出在這邊
: 而這數字是分數 後續會轉成CString 判斷是否 為 "0.00"
: 我的電腦出來的結果是 -0.00 所以不會進入判斷式
: 但是客戶的電腦出來的卻是 0.00 所以會進去 造成意料之外的結果
:
: 請問版友有人有類似的經驗嗎?
: 一樣的程式碼 一樣的執行檔 我個人猜測可能只有CPU演算單元之類的差別
: 還請版友不吝賜教 謝謝
已經回應過的 恕刪
: → uranusjr:其實轉都轉了不如直接加個判斷 -0.00 的條件就好了XD 11/07 22:14
: → uranusjr:如果他轉字串唯一的用途就是這個, 那當然換回正常法很好 11/07 22:15
: → uranusjr:如果這個字串還有用在其他地方的話就... 11/07 22:15
感謝指點 目前只有這用途 所以我也是這樣多加一個判斷^^
: → EdisonX:我倒覺得這問題後段處理較好耶,前段就處理的話等於是直接 11/07 22:18
: → EdisonX:預先定義了系統的最小誤差.另假設eps=1e-9,輸出只有兩個小 11/07 22:19
: → EdisonX:數,那 -0.00 出現也不意外. 11/07 22:19
: → loveme00835: http://ideone.com/Ehvx2o 11/08 02:06
: → loveme00835:std::signbit() 11/08 02:11
: → loveme00835:you should avoid to apply - operator on a zero val 11/08 02:25
請問一下 isless 和 運算子 "<" 有什麼差別嗎?
: → linotwo:http://codepad.org/7Mpw2nn0 11/08 05:54
: → linotwo:或許可以改成 float a = 0 - (float)b; 11/08 05:54
: 推 BlazarArc:hilorrk +1 XD 11/08 09:15
其實這問題好像大家的回覆和我想問的有些微的不一樣 Orz
我重新思考和歸納一下 以及查證了一下wiki
我想問的問題主要還是"為什麼會這樣"和"要怎麼避免"
感謝大家熱心地提供了各種避免的方法m(O)m
不好意思 由於小弟本身非正統資工背景 算是自學 可能有些細節(如浮點數計算)
不是了解的很透測
是故想趁此機會釐清是否有觀念錯誤的地方
加上個人龜毛個性發作 還是很想搞清楚 "為什麼會這樣"
補充說明一下 b是使用者自行給入的值 是扣分用 值域是0~100
這次算是客戶輸入了"0" 這個特別的數值 才引發了當機 導致這次的除錯
測試了一早上 終於發現一點徵兆 拿linotwo兄的程式
http://codepad.org/7Mpw2nn0
在我的VS2008 跑起來都正常 a1 = -0.00
但是在我的VS2003 跑起來 a1 = 0.00
執行檔在客戶的/同事的電腦上 也都是 a1 = 0.00
看來是我的電腦compiler 出了問題@@
請問有人有碰過這種鳥狀況嗎??
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 122.117.112.106
推 LPH66:你看你要不要先去看置底十三誡第十一條裡的那個連結 11/08 14:07
→ LPH66:看完如果還有問題再來問吧 11/08 14:08
→ jokingfish:感謝 指點 馬上去研讀 11/08 14:36
我發現幾年前就曾拜讀過冼老師的這篇文章
觀念不敢說完全正確 大致的觀念還是有的
原本以為給0進float去 可能會變成 0.000001之類 有誤差 才會導致這種結果
可是我發現0 給入變數之後 就變成 0.0e+000f
並沒有文章說的誤差
所以我的猜想是錯的:(
總歸整個狀況 出問題的在Visual Studio 2003版的VC++
我這邊借用linotwo兄的程式 試出來的結果
double b = 0.0;
float a = - (float) b;
printf("a == %.2f %s 0\n", a, a == 0? "==": "!=");
Output:
應該是
a == -0.00 == 0
而我的VS2003 跑出來卻是
a == 0.00 == 0
所以我的理解是 Compiler 自動幫我把負號拿掉了
不知道這樣理解是否正確? 尚請指教 m(o)m
※ 編輯: jokingfish 來自: 122.117.112.106 (11/08 16:51)
→ james732:我想建議你把變數的 binary 表示印出來看看...XD 11/08 17:29
→ diabloevagto:直接印出2進制自己換算 11/08 18:32
→ azureblaze:照標準+0/-0是不同的數字(所以printf不一樣) 11/08 18:38
→ azureblaze:但是標準又規定+0 == -0 11/08 18:38
推 LPH66:其實 printf 會印出 -0.0 還有一個情形是絕對值很小的負數 11/08 18:51
→ LPH66:不過原 PO 的情形應該不太像是這種的... 11/08 18:51