2016-02-12 44 views
0

我正在用C++/Qt做小双数的计算,发生了一些奇怪的事情。在下面的代码中,t_prob的值应该是1.62457e-12,但它是3.24907e-12(如2 * 1.62457e-12)。用C++计算小双数的错误

同时,我用a,b,c和d添加了一个控件,结果是正确的。

你能否给我一些关于这个问题的建议。提前致谢。

#include <QDebug> 
#include <QtMath> 

#define PI 3.1415926536 

double tprob(qint64 n, double x); 

int main(int argc, char *argv[]) 
{ 
    double a = 1.0; 
    double b = 0.00000000000162448; 
    double c = a - b; 
    double d = 1.0 - c; 

    qDebug() << "a:" << a; 
    qDebug() << "b:" << b; 
    qDebug() << "c:" << c; 
    qDebug() << "d:" << d; 

    double df = 127.793; 
    double t_statistic = 9.77749; 
    double ta = tprob(floor(df),-1.0 *t_statistic); 
    double tb = tprob(floor(df), t_statistic); 
    double t_prob = 1.0 - qAbs(ta - tb); 

    qDebug() << "df:" << df; 
    qDebug() << "t_statistic:" << t_statistic; 
    qDebug() << "ta:" << ta; 
    qDebug() << "tb:" << tb; 
    qDebug() << "t_prob:" << t_prob; 


    return 1; 
} 


double tprob(qint64 n, double x){ 
    if(n < 0){ 
    qDebug() << "[error] wrong n value input for tprob"; 
    exit(0); 
    } 

    double a,b,w,z,y,p; 
    w=atan2(1.0 * x/sqrt(n),1); 

    z=cos(w)*cos(w); 
    y=1.0; 
    p=0; 

    for(qint64 i=n-2; i>=2;i-=2){ 
    y= 1 + 1.0 * (i-1)/i * z * y; 
    } 

    if(n%2 ==0){ 
    a=sin(w)/2; 
    b=0.5; 
    }else{ 
    a = (n==1)?0:sin(w)*cos(w)/PI; 
    b = 0.5 + w/PI; 
    } 

    p = 1- b - a * y; 

    if(p>0){ 
    return p; 
    }else{ 
    return 0; 
    } 
} 

输出:

a: 1.62448e-12 
b: 1 
c: 1 
d: 1.62448e-12 
df: 127.793 
t_statistic: 9.77749 
ta: 1 
tb: 1.62457e-12 
t_prob: 3.24907e-12 
+0

可以给你的程序做什么更精确?什么是'df'和't_statistic'变量? –

+0

看起来像浮点精度工作... http://coliru.stacked-crooked.com/a/1b56ef29755bceb0 –

+0

@Marcel这是一个大型项目的一部分,我想在这一节进行t检验,并且完成的公式为t_prob = 1.0- qAbs(tprob(floor(df), - 1.0 * t_statistic) - tprob(floor(df),t_statistic))'''''''''''''''与功能'tprob',它已成功测试。 – ybzhao

回答

1

当你打印的浮点值与<<,默认情况下只得到6级位数精度什么的。

比较:

qDebug() << "c:" << c; 
output: 1 

随着:

qDebug() << "c:" << QString("%1").arg(c, 0, 'g', 15); 
output: "0.999999999998376" 

所以tprob = 1.0 - qAbs(TA - TB)= 1.0 - qAbs(1.0 - 小量 - 小量)= 2 *的ε-

+0

谢谢。你有什么建议可以避免这个问题吗? – ybzhao

+0

谢谢,我已经解决了这个问题。实际上,t_prob的值是正确的。 – ybzhao

+0

是的,这只是一个误导性的显示。 – Ilya