4

これを実行すると、main()でcoutは5.395を出力します。しかし、アサーションは失敗したと言っています!! これは本当に気が遠くなるようなことです、なぜこれが起こっているのですか?

#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に変換し、doubleに戻し、1000で割った。:)

4

3 に答える 3

10

ああ、浮動小数点。

たとえば、 の実際の戻り値が でgetAvgDensity()あるとし5.395000000000000000000000001ます。技術的な話じゃない== 5.395ですよね?もちろん、印刷すると、これらの厄介な末尾の小数はすべて破棄されますが、値は異なります。

フロートを使用する場合、「等しい」の許容可能な定義を自分で決定する必要があります。数値を手動で四捨五入するか、<=/>=および適切な誤差範囲と比較します。

于 2013-03-13T00:21:20.413 に答える
1

これはすでに回答されていますが、2 セント追加します。これを頻繁に行う予定がある場合は、double を比較する関数を作成すると便利です。アイデアは、許容誤差量を表す小さい値が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) );
于 2013-03-13T01:16:47.087 に答える
0

その理由は、デフォルトでは cout がそれほど高い精度で出力されないためです。次のことを試してください。

int main()
{
    std::cout.precision(25);
    cout << getAvgDensity('A') << endl;  // prints 5.395
    assert(getAvgDensity('A')==double(5.395));
    return 0;
}
于 2013-03-13T00:24:50.537 に答える