2013-03-13 66 views
4

當我運行這個,在main()cout打印5.395。但斷言說它失敗了!這真的讓人難以置信,爲什麼會這樣呢?斷言是錯誤的,證明與cout

#include <iostream> 
#include <cassert> 

using namespace std; 

const float A = 1.6; 
const float C = 1.55; 
const float G = 2.2; 
const float T = 1.23; 

char empty[18]; 
int arraySize; 


void copyArray(char sourceArray[], char targetArray[], int size) { 
    for(int i=0;i<size;i++) { 
     targetArray[i] = sourceArray[i]; 
     } 
    } 



double getAvgDensity(char aminoAcid) { 

char aminoUpper = toupper(aminoAcid); 
aminoToArray(aminoUpper); 
    double counter = 0; 
    int codonTotal = arraySize/3.0; 
    if (arraySize == 0) 
     return 0; 
    else 
    { 
    for (int i = 0; i < arraySize; i++) { 
     counter += charToDouble(empty[i]); 
     } 

    return (counter/codonTotal); 
    } 

} 


int main() 
{ 
    cout << getAvgDensity('A') << endl; // prints 5.395 
    assert(getAvgDensity('A')==5.395); 
    return 0; 
} 

編輯:感謝所有的答案,我只是乘以1000,轉換成int,轉換回雙和除以1000 :)

+11

我敢打賭,你comparig一個浮點值,是不是precesely是...;) – 2013-03-13 00:16:48

+0

請訪問http:// stackoverflow.com/questions/1839422/strange-output-in-comparison-of-float-with-float-literal?rq=1 – 2013-03-13 00:18:13

+0

如何在不更改斷言聲明的情況下解決此問題? – Foxic 2013-03-13 00:19:45

回答

10

啊,浮點。

舉例說,getAvgDensity()的實際回報是5.395000000000000000000000001。這在技術上不是== 5.395,是嗎?當然,打印會丟棄所有那些討厭的尾隨小數,但是值仍然不同。

在使用浮動工具時,您必須自己決定什麼是「等於」的可接受定義。手動舍入數字,或將其與<=/>=和適當的誤差範圍進行比較。

0

原因是cout默認情況下不打印到那麼高的精度。請嘗試以下操作:

int main() 
{ 
    std::cout.precision(25); 
    cout << getAvgDensity('A') << endl; // prints 5.395 
    assert(getAvgDensity('A')==double(5.395)); 
    return 0; 
} 
+0

'5.395'已經是雙倍的了。演員陣容不會改變任何事情。 – 2013-03-13 01:04:15

+0

演員並非必要,但不影響任何內容。如果您閱讀代碼上方的註釋,您會看到原因。順便說一下,演員不會刪除斷言。該代碼修改了cout的精度。 – user1952500 2013-03-13 01:42:00

+0

上面的代碼不會刪除斷言,但可以通過打印高精度雙精度來幫助用戶更好地理解。更好地閱讀代碼上方的註釋,瞭解代碼的作用。 – user1952500 2013-03-13 01:54:09

1

這已經得到了解答,但我會補充我的兩分錢。如果你打算經常這樣做,你可能會發現做一個比較雙打的函數是有用的。這個想法是檢查fabs(a-b) < epsilon,其中epsilon是一個代表可容許錯誤量的小值。

bool is_equal(double a, double b, const double epsilon = 1e-5) 
{ 
    double c = a - b; 
    return c < epsilon && -c < epsilon; // or you could use fabs(c) < epsilon 
} 

然後,它只是這樣做的一個案例:

assert(is_equal(getAvgDensity('A'), 5.395));