[英]strange double to int conversion behavior in c++
以下程序顯示了我在c ++中看到的奇怪的double to int轉換行為:
#include <stdlib.h>
#include <stdio.h>
int main() {
double d = 33222.221;
printf("d = %9.9g\n",d);
d *= 1000;
int i = (int)d;
printf("d = %9.9g | i = %d\n",d,i);
return 0;
}
當我編譯並運行程序時,我看到:
g++ test.cpp
./a.out
d = 33222.221
d = 33222221 | i = 33222220
為什么我不等於33222221? 編譯器版本是GCC 4.3.0
浮點表示幾乎從不精確(僅在特殊情況下)。 每個程序員都應該讀到: 每個計算機科學家應該知道的關於浮點運算的內容
簡而言之 - 您的號碼可能是33222220.9999999999999999999999999999999999999999999999999999999999999999998(或類似的東西),截斷后變為33222220。
當你附加一個調試器,檢查值,你會看到的價值d
實際上是33222220.999999996
,當轉換為整數,這是正確截斷為33222220。
可以存儲在雙變量中的數量有限,而33222221不是其中之一。
由於浮點近似,33222.221實際上可能是33222.220999999999999。 乘以1000得出33222220.999999999999。 強制轉換為整數會忽略所有小數(向下舍入),最終結果為33222220。
如果將printf()
調用中的“9.9g”更改為17.17以使用64位IEEE 754 FP編號恢復所有可能的精度數字,則獲得雙精度值33222220.999999996。 然后int轉換是有道理的。
我不想重復其他評論的解釋。
所以,這里只是一個建議,以避免像所描述的問題:
盡可能避免浮點算法(特別是涉及計算時)。
如果確實需要浮點算術,那么一定不能通過operator ==比較數字! 使用你自己的比較函數(或使用一些庫提供的函數),使用某種epsilon比較(絕對或相對於數字的magniture)做類似“幾乎相等”的比較。
例如,參見優秀的文章
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
由布魯斯道森代替!
斯特凡
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.