我对双重格式的精确度有疑问。
示例示例:
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'声明。
我如何纠正这种差异?还有其他方法可以求和吗?
答案 0 :(得分:5)
在双精度IEEE 754二进制浮点格式(在英特尔和其他处理器上使用的格式)0.1 + 0.2 == 0.30000000000000004
:-)和0.30000000000000004 != 0.3
的世界中(并注意到在奇妙的世界中{ {1}} s,0.1,0.2和0.3不存在“精确”数量。有一些非常靠近它们的双数,但如果你用完全精度打印它们,它们将不是0.1,0.2和0.3)
要笑一点,试试这个:http://pages.cs.wisc.edu/~rkennedy/exact-float
插入一个十进制数字并查看第二行和第三行,它显示数字在内存中的实际表示方式。它适用于Delphi,但double
和Double
对于Delphi和可能是所有C处理器的英特尔处理器都是相同的(在C中称为Single
和double
< / p>
如果您想亲自尝试,请查看此http://ideone.com/WEL7h
float
输出:
3.00000000000000044409e-01
2.99999999999999988898e-01
(请注意,输出取决于编译器。根据选项,#include <stdio.h>
int main()
{
double d1 = (0.1 + 0.2);
double d2 = 0.3;
printf("%.20e\n%.20e", d1, d2);
return 0;
}
可以编译并舍入为0.3)
答案 1 :(得分:1)
与整数值不同,浮点值的存储方式与为其赋值的方式完全不同。让我们考虑以下代码:
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(a-b) < threshold )
return true;
else
return false;
答案 2 :(得分:0)
任何两个不同的实数之间有无数的实数。如果我们能够代表其中的每一个,我们就需要无限的记忆。由于我们只有有限的内存,因此需要以有限的精度存储浮点数。达到该有限精度,可能不是0.1 + 0.2 <= 0.3。
现在,你真的应该阅读Paul R提供的优秀链接另一端的内容。