看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《caxz ( )》之銘言: : 問題三 : int main() : { : float a = 0.7; : if(a > 0.7) cout<< "C" <<endl; : else cout<< "C++" <<endl; : //以上這段印出C++ : if(a < 0.7) : cout<< "C" <<endl; : else : cout<< "C++" <<endl; : //以上這段印出C : } : 這看似簡單但我卻想不通....有什麼到原因是這樣的output ?? ____ 0.7 無法以二進位有限小數表示, 將其轉為二進位是為 0.10110 因此實際上電腦看到的不是 0.7, 而是依照其精確度留存的二進位近似值 取 float 切 24 位有效位數會得到 0.101100110011001100110011 | 0... 因此這個 a 變數實際上存的值是二進位的 0.101100110011001100110011 而單寫 0.7 其形態為 double, 切 53 位有效位數得 0.10110011001100110011001100110011001100110011001100110 | 0... 因此 a 跟 0.7 比較即是比較下列兩數的大小: a 0.101100110011001100110011 0.7 0.10110011001100110011001100110011001100110011001100110 由此 a < 0.7 會成立 : 後來又被問到 如果 a 的行型態被改為 double 呢? : 我剛剛是try了一下 結果都是C++ : 為何會有這種改變呢? 這時這兩個數都是 double 的那個 0.7 所以兩者相等, 兩個不等的比較都不成立 --- 題外話, 這兩個數精確地轉回十進位是 float -> 0.699999988079071044921875 double -> 0.6999999999999999555910790149937383830547332763671875 --- 既然這是面試題 我覺得你只要能答出前一種狀況會一個成立一個不成立 後一種狀況則會都不成立, 應該基本觀念就有了 (前一種狀況改不同的數結果會不同, 例如若改 0.6 則是 a > 0.6 成立 改 0.5 則是 a > 0.5 跟 a < 0.5 都不成立) -- LPH [acronym] = Let Program Heal us -- New Uncyclopedian Dictionary, Minmei Publishing Co. -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.195.39.85 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1438361169.A.590.html
chrisdar: Q3 真的只是想考 有沒看過 IEEE754 而已吧~ 08/01 01:04
chrisdar: 更正, Q3 考的是 1.IEEE754 2.字面常量 08/01 01:07
Feis: IEEE 754 不是 C 或 C++ 的必備條件. 還是要看編譯器 08/01 01:08
stupid0319: 是在考組語fld,fcomip 怎麼運作的嗎? 08/01 01:09
Feis: 要我說的話應該就是對浮點數的危機感而已 08/01 01:09
chrisdar: 有些編譯器會提醒二元比較運算元 的 左右方資料寬度不同 08/01 01:12
chrisdar: 遇到不會提示的 debug起來真的就完全沒有頭緒 08/01 01:14
IEEE754 在這個回答裡只是當做二進位科學記號來看而已 浮點數這種東西就算實作不同, 骨子裡都還是科學記號 (這點原 PO 可以記下來) 因此一些科學記號的概念換個底就能通用, 例如有效數字、計算誤差等等 前一種狀況就算浮點數不是 IEEE754, 只要都是科學記號表示就一定會有一大一小 另外 chrisdar 提到的 literal fp 的型態算是隱藏考題 不知道這個的話後一種狀況跟前一種就沒有差別了 所以我才會說合格的回答是「前一種兩者恰有一成立,後一種兩者皆不成立」 ※ 編輯: LPH66 (123.195.39.85), 08/01/2015 01:42:09
name2name2: 推 08/01 08:20
cuteSquirrel: 優質好文 08/01 10:18
EdisonX: 我想問一般在取有效位數是看後一位是 0/1 做 +1 嗎? 08/01 14:51
EdisonX: 像 0.0011 | 1 看4位,最後是 0.0011 / 0.0100 ? 08/01 14:51
OSDBNetwork: 高手中的高手 08/01 15:16
LiloHuang: 0.7f 08/01 15:25
Feis: EdisonX: "一般" 的話,預設是往偏差值少的地方移動 08/01 15:54
Feis: 如果往大往小都一樣, 則往雙數走. 這例子應該是 0.0100 08/01 15:55
Feis: 實際上的話應該還是看實作品. 無條件進位或捨去也都是可能 08/01 15:55
Feis: 如果要研究的話還有正負數可以玩呢~ 08/01 15:56
Feis: 有興趣的話可以複習一下 " 四捨六入五成雙" 08/01 16:01
Jkx: 08/01 17:56
EdisonX: 謝謝feis 08/01 21:30
kidbower: wow 08/02 22:38