看板 C_and_CPP 關於我們 聯絡資訊
大家好 想請教一個double的問題 double d = 2.32605000; uint32_t i = 2; double m = d - i; uint32_t x = d * 1000000; uint32_t y = m * 1000000; printf("x=%d, y=%d", x, y); 印出來x是2326050沒問題 但y卻是326049 這是print的precision問題嗎? 或是因爲double的binary表示的關係 謝謝! -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.161.39.15 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1677055960.A.7DE.html ※ 編輯: tstanly (118.161.39.15 臺灣), 02/22/2023 16:56:44
yvb: 你還沒 printf 前就都轉成整數了不是嗎? 02/22 18:03
yvb: 另外實測 32-bit -O0 兩個尾數都會是 49 . 02/22 18:03
yvb: 但是 32-bit -O1 或 64-bit 的結果, 尾數就是 50 和 49. 02/22 18:06
nh60211as: 兩個數字都無法完整用double來表示 02/22 19:58
nh60211as: https://i.imgur.com/j69EN6Y.png 02/22 19:58
nh60211as: https://i.imgur.com/UwKCwAP.png 02/22 19:58
nh60211as: 另外浮點數運算在不同的架構、編譯器、編譯選項都可能 02/22 19:58
nh60211as: 有不同的結果 02/22 19:58
nh60211as: https://godbolt.org/z/1P5zzhEKz 02/22 19:59
nh60211as: 可以參考上面都是GCC開不同編譯選項,實際產生的code 02/22 19:59
nh60211as: 完全不一樣 02/22 19:59
tstanly: 謝謝。從assembly code看起來 326049是compiler先算的(爲 02/23 16:39
tstanly: 了optimization)。只是不懂爲什麼它這樣算了。 02/23 16:39
nh60211as: 因為你的程式碼只有可能產生一種輸出,如果你把這段邏 02/23 17:38
nh60211as: 輯寫成一個function的話那編譯器就不可能先把輸出寫到 02/23 17:38
nh60211as: 程式裡面了 02/23 17:38
LPH66: 之所以這裡會有這種差就是取整時是截斷取整而非最接近取整 02/24 18:27
LPH66: 那這一點如上所述跟不同架構不同編譯器不同編譯選項都有關 02/24 18:27
hellophoenix: 用double d=3.326950000000000l看看 03/08 23:10
hellophoenix: 感覺宣告d的時候是把0.32605的float給了d所以造成 03/08 23:12
hellophoenix: 精度損失 03/08 23:12
yvb: 樓上請看一下五樓和六樓的圖片吧. 03/08 23:44