【问题标题】:C float and double comparisonsC浮点和双重比较
【发布时间】:2016-05-10 13:28:09
【问题描述】:

我正在比较 C 中的简单浮点数和双精度数,特别是它们的值 8.7。现在我将 8.7 分配给每个变量,当我打印时,两个值的结果都是 8.7000。为什么编译器添加了这些零。我想问的主要问题是我没有看到更多的数字,比如隐藏在尾随零之后。我读到,由于缺乏精度,我不应该用 float 进行这样的比较,但我认为用这么小的值肯定可以存储 8.7 并具有与另一个 8.7 值进行比较所需的准确度?

我唯一担心的是它实际上在内存中的某个地方被表示为例如 8.70000003758 或其他东西,这让我的比较失败了?我尝试使用 %.20f 打印以查看可能隐藏的任何其他数字,但我认为这只是创建了原本不存在的数字,因为数字的整体准确性更改为 8.6918734634834929 或类似的东西。

【问题讨论】:

  • 1/3 是一个很小的值。但是没有固定精度的十进制表示可以准确地存储它。你的推理完全无效。
  • 如果你真的想看看差异,试着在 gdb 中运行应用程序并查看这两个变量。您将能够看到内部表示。您必须查看上述评论中浮点数的表示方式。

标签: c floating-point double precision floating-accuracy


【解决方案1】:

我正在比较 C 中的简单浮点数和双精度数,特别是两者的值 8.7。

错误的选择,因为 8.7 没有精确的二进制表示。

现在我将 8.7 分配给每个变量,当我打印时,两个值的结果都是 8.7000。为什么编译器添加了这些零。

没有,你的打印程序有。

我想问的主要问题是,是否还有我没有看到的其他数字,例如隐藏在尾随零之后的数字。

当然,因为 8.7 没有精确的二进制表示。 (试着把它写成2的整数幂之和,你做不到。)

我读到,由于缺乏精度,我不应该用 float 进行这样的比较,但我认为用这么小的值肯定可以存储 8.7 并具有与另一个 8.7 值进行比较所需的准确度?

你想错了。 1/3 很小,但没有精确的十进制表示,位数有限。一个值是大是小,与它能否用特定基数的有限位数精确表示无关。

我唯一担心的是它实际上在内存中的某个地方被表示为例如 8.70000003758 或其他东西,这让我无法进行比较?

完全正确,就像 0.333333333 那样表示 1/3。

我尝试使用 %.20f 打印 f 以查看可能隐藏的任何其他数字,但我认为这只是创建了原本不存在的数字,因为数字的整体准确性更改为 8.6918734634834929 或类似的东西。

这可能只是一个错误。向我们展示该代码。也许你试图输出一个双精度而忽略了l

【讨论】:

  • 好的,感谢您的明确答复。有没有办法截断某个小数点后的任何数字,以便为我的目的进行准确的比较。我想要的只是一个可以比较的十进制数 float != double 。但我需要一个大致准确的数字,即使到 1 dp 也可以
  • @JohnSetter 请不要比较浮点数的相等性,即使它们是相同的类型 - 不要介意不同的类型。见Is floating point math broken?
  • 您可以轻松比较浮点数的近似相等性。简单的方法是使用if(fabs(a - b) < 0.001) 之类的代码。请参阅 C 常见问题解答列表以获得更好的答案:c-faq.com/fp/fpequal.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 2015-10-22
  • 2013-03-12
  • 1970-01-01
  • 2011-04-19
  • 2011-10-24
相关资源
最近更新 更多