比较C ++中的两个float变量

时间:2019-05-08 11:25:19

标签: c++ floating-point

我已经阅读了多篇有关浮点变量比较的文章,但未能理解这些文章并从中获得必需的知识。所以,我在这里发布这个问题。

比较两个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变量都具有不同的值。

3 个答案:

答案 0 :(得分:5)

没有通用的解决方案来比较包含先前操作中的错误的浮点数。必须使用的代码是特定于应用程序的。因此,要获得正确的答案,您必须更具体地描述您的情况。

潜在的问题是使用错误的数据执行正确的计算通常是不可能的。如果您想计算两个精确数学值 x y 的某个函数,但您仅有的数据是一些不精确计算的值x和{{1} },通常不可能计算出完全正确的结果。例如,假设您想知道 x + y 的总和,但是您只知道y为3,而x为4,但您不知道什么是真正的确切 x y 。这样就无法计算 x + y

如果您知道yx大约 x y ,则可以计算出一个通过添加yx来近似 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.012345678float不是 @Rudy Velthuis

1.012345 67165374755859375 // `float` member
1.012345 678
1.012345 679
1.012345 790863037109375   // `float` member

类似的方法适用于double,但精度更高-通常为64位。

1.0123456791.012345678double中设置为不是

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

ab具有相同的值。

答案 2 :(得分:-3)

这是因为浮点数具有7位精度。 如果要提高精度,则需要使用double或long double。