C – 双精度求和

我有双格式精度的问题。


示例示例:

double K=0, L=0, M=0; scanf("%lf %lf %lf", &K, &L, &M); if((K+L) <= M) printf("Incorrect input"); else printf("Right, K=%f, L=%f, M=%f", K, L, M); 

我的测试输入:

K = 0.1,L = 0.2,M = 0.3 – >条件但是转到‘else’语句。


我怎么能纠正这种差异? 还有其他方法可以求和吗?

在双精度IEEE 754二进制浮点格式(英特尔和其他处理器上使用的格式)的世界中, 0.1 + 0.2 == 0.30000000000000004 :-)和0.30000000000000004 != 0.3 (注意在double s的奇妙世界中,0.1 ,0.2和0.3不存在“精确”数量。有一些非常靠近它们的双数,但如果你用完全精度打印它们,它们将不是0.1,0.2和0.3)

要笑一点,试试这个: http : //pages.cs.wisc.edu/~rkennedy/exact-float

插入十进制数并查看第二行和第三行,它显示数字在内存中的实际表示方式。 它适用于Delphi,但对于Delphi和可能所有用于Intel处理器的C编译器而言, DoubleSingle是相同的(它们在C中称为doublefloat

如果您想亲自尝试,请查看http://ideone.com/WEL7h

 #include  int main() { double d1 = (0.1 + 0.2); double d2 = 0.3; printf("%.20e\n%.20e", d1, d2); return 0; } 

输出:
3.00000000000000044409e-01
2.99999999999999988898e-01

(请注意,输出取决于编译器。根据选项,可以编译0.1 + 0.2并舍入为0.3)

与整数值不同,浮点值的存储方式与为其赋值的方式完全不同。 让我们考虑以下代码:

 int i = 1; // this is and always will be 1 float j = 0.03 // this gets stored at least on my machine as something like 0.029999999 

为什么会这样? 那么在0.1和0.2之间的区间内存在多少个浮点数? 一个无限的数字! 因此,有些值会按照您的意图存储,但会有很多值存储在一起,会出现一个小错误。

这就是为什么比较浮点值的平等不是一个好主意。 尝试这样的事情:

 float a = 0.3f; float b = 0.301f; float threshold = 1e-6; if( abs(ab) < threshold ) return true; else return false; 

在任何两个不同的实数之间存在无限多个实数。 如果我们能够代表其中的每一个,我们就需要无限的记忆。 由于我们只有有限的内存,因此需要以有限的精度存储浮点数。 达到有限精度,0.1 + 0.2 <= 0.3可能并非如此。

现在,你真的应该阅读Paul R.提供的优秀链接另一端的内容。