【问题标题】:floating point numbers equality checking浮点数相等检查
【发布时间】:2013-08-09 07:56:13
【问题描述】:

使用以下代码,

#include <stdio.h>

int main(void){
  float x;
  x=(float)3.3==3.3;
  printf("%f",x);
  return 0;
}

输出为 0.00000

但是当数字3.3换成3.5时,

#include <stdio.h>

int main(void){
  float x;
  x=(float)3.5==3.5;
  printf("%f",x);
  return 0;
}

输出为 1.0000

为什么输出会有差异?

【问题讨论】:

标签: c floating-point


【解决方案1】:

你应该明白,在 C 中,文字 3.3 的类型是 double。将 double 转换为 float 可能会丢失精度,因此 3.3F 与 3.3 的比较结果为 false。对于 3.5,转换是无损的,因为两者都可以精确表示并且比较结果为真。

这与比较(以 10 为底,而不是以 2 为底)有点相关

3.3333333 with 3.3333333333333333  (false)
3.5000000 with 3.5000000000000000  (true)

【讨论】:

  • 知道发生了什么的另一部分是(float)3.3值在比较之前被提升回double
  • @caf:很高兴知道这一点,但这与这个问题无关。只要== 当且仅当左操作数等于右操作数时才返回 true,它是否提升其中一个操作数或实现某种直接比较都无关紧要。 (float) 3.3 == 3.3 无论如何都会返回相同的结果。
【解决方案2】:

由于舍入误差,大​​多数浮点数字最终有点不精确。只要这种不精确性很小,通常可以忽略不计。但是,这也意味着预期相等的数字(例如,通过不同的正确方法计算相同结果时)通常会略有不同,简单的相等性测试会失败。

在您的情况下,将 double 转换为 float 会损失一些精度。

比较浮点数时必须非常小心。

我建议你看看这个链接:What is the most effective way for float and double comparison?

这篇文章可能会帮助你理解它为什么附加:http://www.cprogramming.com/tutorial/floating_point/understanding_floating_point_representation.html


关于浮点数的一点解释以及为什么会发生这种情况:

浮点数通常作为符号位指数字段有效位(尾数)打包到计算机数据中, 从左到右。

基本上,你可以说一个浮点数是:

number = (sign ? -1:1) * 2^(exponent) * 1.(mantissa bits)

当然,根据您使用的是 float 还是 double,精度会有所不同:

          | Sign | Exponent | Significand | Total bits
float     | 1    | 8        | 23          | 32
Double    | 1    | 11       | 52          | 64

在这里您可以了解为什么将双精度数转换为浮点数可能会丢失一些数据。

在您的情况下,计算机似乎能够精确计算 3.5,但不能精确计算 3.3。 不知何故,使用公式,我们可能会假设您正在做类似的事情:

3.3333333 == 3.333333333333333   // is false because of the precision
3.5000000 == 3.500000000000000   // is true

// I tried to match the precision of the float in the left
// and the precision of the double on the right

【讨论】:

    【解决方案3】:

    == 执行相等检查。浮点数的平等检查有问题(请参阅http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm)

    所以,一旦你得到一个假,一旦你得到一个真 (1)。

    有关比较浮点数的更可靠的方法,请参阅 - What is the most effective way for float and double comparison?

    【讨论】:

    • 注意:Bruce Dawson 更新了他的条目以引用博客条目(比较浮点数,2012 版)[randomascii.wordpress.com/2012/02/25/….而相关的 SO Q&A 在处理浮点比较方面实际上是不完整的。 (即使只是主要问题,也没有一个单一的答案是全面的)。
    【解决方案4】:

    不同的是,3.5可以精确地表示为二进制浮点数,而3.3不能。

    由于数学 3.3 无法精确表示,3.3 作为双精度数,比单精度数 (float)3.3 更接近,因此具有不同的值。

    【讨论】:

      【解决方案5】:

      Why is there a difference in output?

      戴上数学/CS () 帽子的理论但可能不令人满意的答案是:

      • 因为浮点数是有限的,因此不等于我们在数学(以及大部分现实世界)中习惯使用的 R http://mathurl.com/mgwavz7 数字。
      • 浮点数是二进制而不是十进制,因此某些分数在十进制表示中是有限的,但在二进制(或基数 2)。

      @詹斯

      【讨论】:

        猜你喜欢
        • 2015-07-08
        • 2018-12-10
        • 2020-07-31
        • 1970-01-01
        • 2023-03-07
        • 2017-10-18
        • 2012-11-18
        • 2011-05-01
        相关资源
        最近更新 更多