断言是错的,用证据证明

Assert is wrong, proven with cout

本文关键字:证据 证明 断言      更新时间:2023-10-16

当我运行这个时,在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,转换回双精度,除以1000。:)

啊,浮点数

例如,getAvgDensity()的实际返回值是5.395000000000000000000000001。严格来说不是== 5.395,对吧?当然,打印会丢弃所有这些烦人的尾随小数,但值仍然不同。

当使用浮点数时,你必须自己决定什么是"equal"的可接受定义。手动四舍五入,或与<=/>=和合适的误差范围进行比较。

这个问题已经有人回答了,但我还是要补充一下我的观点。如果您打算经常这样做,您可能会发现创建一个函数来比较双精度体是很有用的。这个想法是检查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) );

原因是cout在默认情况下不会打印到那么高的精度。试试以下命令:

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