双等于C 0问题 [英] Double equals 0 problem in C

查看:118
本文介绍了双等于C 0问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现算法用C来计算自然对数。

 双taylor_ln(INT Z){
    双总和= 0.0;
    双TMP = 1.0;    INT I = 1;
    而(TMP!= 0.0){
        TMP =(1.0 / I)*(POW(((Z - 1.0)/(Z + 1.0)),I));
        的printf((1.0 /%D)*(POW(((%d个 - 1.0)/(%D + 1.0)),%D))=%F \\ N,I,Z,Z,I,TMP) ;
        总和+ = tmp目录;
        I + = 2;
    }    返回总和* 2;
}

如由打印语句,TMP确实等于0.0最终,然而,循环继续。可能是什么原因?

我在Fedora 14 AMD64和编译:

 铛-lm -o taylor_ln taylor_ln.c


例如:

  $ ./taylor_ln 2
(1.0 / 1)*(POW(((2 - 1.0)/(2 + 1.0)),1))= 0.333333
(1.0 / 3)*(POW(((2 - 1.0)/(2 + 1.0)),3))= 0.012346
(1.0 / 5)*(POW(((2 - 1.0)/(2 + 1.0)),5))= 0.000823
(1.0 / 7)*(POW(((2 - 1.0)/(2 + 1.0)),7))= 0.000065
(1.0 / 9)*(POW(((2 - 1.0)/(2 + 1.0)),9))= 0.000006
(1.0 / 11)*(POW(((2 - 1.0)/(2 + 1.0)),11​​))= 0.000001
(1.0 / 13)*(POW(((2 - 1.0)/(2 + 1.0)),13))= 0.000000
(1.0 / 15)*(POW(((2 - 1.0)/(2 + 1.0)),15))= 0.000000
(1.0 / 17)*(POW(((2 - 1.0)/(2 + 1.0)),17))= 0.000000
(1.0 / 19)*(POW(((2 - 1.0)/(2 + 1.0)),19))= 0.000000
(1.0 / 21)*(POW(((2 - 1.0)/(2 + 1.0)),21))= 0.000000
等等...


解决方案

浮点比较是精确的,所以 10 ^ -10 是不一样的 0.0

基本上,你应该对一些容忍的差异来比较,说 10 ^ -7 根据你写出来小数,可作为完成的数量:

 而(晶圆厂(TMP)> 10E-7)

I was implementing an algorithm to calculate natural logs in C.

double taylor_ln(int z) {
    double sum = 0.0;
    double tmp = 1.0;

    int i = 1;
    while(tmp != 0.0) {
        tmp = (1.0 / i) * (pow(((z - 1.0) / (z + 1.0)), i));
        printf("(1.0 / %d) * (pow(((%d - 1.0) / (%d + 1.0)), %d)) = %f\n", i, z, z, i, tmp);
        sum += tmp;
        i += 2;
    }

    return sum * 2;
}

As shown by the print statement, tmp does equal 0.0 eventually, however, the loop continues. What could be causing this?

I am on Fedora 14 amd64 and compiling with:

clang -lm -o taylor_ln taylor_ln.c


Example:

$ ./taylor_ln 2
(1.0 / 1) * (pow(((2 - 1.0) / (2 + 1.0)), 1)) = 0.333333
(1.0 / 3) * (pow(((2 - 1.0) / (2 + 1.0)), 3)) = 0.012346
(1.0 / 5) * (pow(((2 - 1.0) / (2 + 1.0)), 5)) = 0.000823
(1.0 / 7) * (pow(((2 - 1.0) / (2 + 1.0)), 7)) = 0.000065
(1.0 / 9) * (pow(((2 - 1.0) / (2 + 1.0)), 9)) = 0.000006
(1.0 / 11) * (pow(((2 - 1.0) / (2 + 1.0)), 11)) = 0.000001
(1.0 / 13) * (pow(((2 - 1.0) / (2 + 1.0)), 13)) = 0.000000
(1.0 / 15) * (pow(((2 - 1.0) / (2 + 1.0)), 15)) = 0.000000
(1.0 / 17) * (pow(((2 - 1.0) / (2 + 1.0)), 17)) = 0.000000
(1.0 / 19) * (pow(((2 - 1.0) / (2 + 1.0)), 19)) = 0.000000
(1.0 / 21) * (pow(((2 - 1.0) / (2 + 1.0)), 21)) = 0.000000
and so on...

解决方案

The floating point comparison is exact, so 10^-10 is not the same as 0.0.

Basically, you should be comparing against some tolerable difference, say 10^-7 based on the number of decimals you're writing out, that can be accomplished as:

while(fabs(tmp) > 10e-7)

这篇关于双等于C 0问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆