c++ - 为什么我的浮点值看起来不等于它本身?

标签 c++ floating-point

<分区>

#include<iostream.h>
using namespace std;
int main()
{
      float x=1.1;
      if(x==1.1)
         cout<<"yes";
      else
         cout<<"no";
      return 0;
}

我给 x 赋值 1.1,检查 x 的值是否为 1.1?

最佳答案

您已经进入了几乎所有编程语言的一个有趣领域。浮点值是棘手的事情,很少建议测试它们是否相等。基本问题是现代计算机上的浮点值表示为精度有限的二进制小数。

为了更容易理解,让我们使用以 10 为基数的小数,并使用无法用它们准确表示的数字。取1/3。如果您将其表示为以 10 为基数的小数,您会得到:

0.̅3(如果显示不正确,则在三个上方有一个横条)。基本上,它会永远持续下去,没有有限的数字可以完美准确地表示 1/3 作为十进制小数。所以,如果你只有那么多数字,你把它砍掉并近似:

0.333333

实际上是 333333/1000000,非常接近 1/3,但不完全是。

C++ 有几种不同的浮点类型。这些类型通常(取决于编译程序的平台)具有不同数量的有效数字。默认情况下,浮点常量是 double 类型,它的位数通常比 float 多(而且永远不会少)。同样,以 10 为基数作为示例,因为您将值存储在 float 中,所以您正在做这样的事情:

0.333333 == 0.3333333333333333333

这当然是错误的。

如果你这样写你的代码:

#include <iostream>
using namespace std;
int main()
{
      float x = 1.1f;
      if(x == 1.1f)
         cout<<"yes";
      else
         cout<<"no";
      return 0;
}

您可能会得到预期的结果。将 f 放在裸浮点值(也称为浮点文字)的末尾,告诉 C++ 它是 float 类型。

当然,这一切都非常吸引人,而且还有很多内容需要深入了解。如果你想了解更多关于 float 是如何表示的,有一个很好的 Wikipedia page on IEEE 754 floating point representation ,这是当今大多数现代处理器表示 float 的方式。

从实际的角度来看,您应该很少(如果有的话)比较 float 是否相等。通常,这样做的愿望表明您的程序中存在某种设计缺陷。如果您真的必须使用“epsilon”比较。基本上,测试你的数字是否“足够接近”,尽管确定这在任何给定情况下意味着什么并不一定是一项微不足道的任务,这就是为什么如果你需要比较它们是否相等,它通常代表设计缺陷.但是,在您的情况下,它可能看起来像这样:

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
      float x=1.1;
      if (fabs(x - 1.1) < 0.000001)
         cout<<"yes";
      else
         cout<<"no";
      return 0;
}

关于c++ - 为什么我的浮点值看起来不等于它本身?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53975208/

相关文章:

c++ - 多次迭代后的 BadPtr

R:计算 log(exp(...)) 的最大浮点误差

c++ - 两个条件不一样,我不明白为什么

c++ - 使用 memcpy() 函数将字节从 unsigned char 数组放入 std::string

c++ - 多线程控制台 I/O

c++ - 如何在 C++ 中更改继承类型的访问类型?

c - 编写一个函数来测试点是否在矩形中

math - float 学有问题吗?

c# - 将 24 位值转换为 float 并返回

java - 为什么Java中的浮点计算比C慢