我已经阅读了多篇有关浮点变量比较的文章,但未能理解这些文章并从中获得必需的知识。所以,我在这里发布这个问题。
比较两个float变量的好方法是什么? 下面是代码片段:
#define EPSILON_VALUE 0.0000000000000001
bool cmpf(float A, float B)
{
return (fabs(A - B) < EPSILON_VALUE);
}
int main()
{
float a = 1.012345679, b = 1.012345678;
if(cmpf(a, b))cout<<"same"<<endl;
else cout<<"different"<<endl;
return 0;
}
输出:same
,尽管两个float变量都具有不同的值。
答案 0 :(得分:5)
没有通用的解决方案来比较包含先前操作中的错误的浮点数。必须使用的代码是特定于应用程序的。因此,要获得正确的答案,您必须更具体地描述您的情况。
潜在的问题是使用错误的数据执行正确的计算通常是不可能的。如果您想计算两个精确数学值 x 和 y 的某个函数,但您仅有的数据是一些不精确计算的值x
和{{1} },通常不可能计算出完全正确的结果。例如,假设您想知道 x + y 的总和,但是您只知道y
为3,而x
为4,但您不知道什么是真正的确切 x 和 y 。这样就无法计算 x + y 。
如果您知道y
和x
大约 x 和 y ,则可以计算出一个通过添加y
和x
来近似 x + y。当要计算的函数(在此示例中为y
)具有合理的导数时,这些作品就可以工作:用合理的导数稍微更改函数的输入会稍微改变其输出。当您要计算的函数具有不连续性或较大的导数时,此操作将失败。例如,如果您想使用近似值+
计算 x 的平方根(在实际域中),但由于先前的舍入误差,x
可能为负,则计算x
可能会产生异常。同样,比较不平等或顺序是一个不连续的函数:输入的微小变化可以完全改变答案(从假到真,反之亦然)。
常见的坏建议是与“宽容”相比较。此方法将假阴性(如果比较精确的数学值,则不正确地拒绝满足比较的数字)与假阳性(错误地接受不满足比较的数字)。
适用者是否可以容忍错误接受取决于应用程序。因此,没有通用的解决方案。
要设置的公差级别,甚至是计算公差的能力,都取决于数据,误差和先前的计算。因此,即使可以与公差进行比较,公差的使用量和计算方法也取决于应用程序。没有通用的解决方案。
答案 1 :(得分:1)
输出:相同,尽管两个float变量都具有不同的值。
“浮点变量具有不同的值。”是没有根据的。
same
被打印是因为即使初始化常量不同,值a,b
也相同。
Typical float
是32位,可以表示大约2 32 个不同的值,例如1.0、1024.0、0.5、0.125。这些值的形式均为:+/- some_integer * 2 some_integer
1.012345679
中, 1.012345678
和float
不是 。 @Rudy Velthuis。
1.012345 67165374755859375 // `float` member
1.012345 678
1.012345 679
1.012345 790863037109375 // `float` member
类似的方法适用于double
,但精度更高-通常为64位。
1.012345679
和1.012345678
在double
中设置为不是
1.012345 67799999997106397131574340164661407470703125 // `double` member
1.012345 678
1.012345 6780000001931085762407747097313404083251953125 // `double` member
...
1.012345 6789999998317597373898024670779705047607421875 // `double` member
1.012345 679
1.012345 67900000005380434231483377516269683837890625 // `double` member
可以将其视为2个舍入步骤。代码1.012345679
舍入到最接近的double
1.01234567900000005380434231483377516269683837890625。然后,分配将double
舍入到最接近的float
1.01234567165374755859375。
float a = 1.012345679;
// 'a' has the value of 1.01234567165374755859375
与b
类似。代码1.012345678
会四舍五入为最接近的double
1.0123456779999999719719797131574340164661407470703125。然后,分配将double
舍入到最接近的float
1.01234567165374755859375。
flaot b = 1.012345678;
// 'b' has the value of 1.01234567165374755859375
a
和b
具有相同的值。
答案 2 :(得分:-3)
这是因为浮点数具有7位精度。 如果要提高精度,则需要使用double或long double。