浮点和双常数比较

float and double constant comparing

本文关键字:常数 比较      更新时间:2023-10-16

来源http://www.cprogramming.com/tips/tip/difference-between-float-and-double:

在c++中,任何类似4.12的值默认情况下都被视为双精度。由于导致微小误差的精度差异。例如:

float a = 4.12;
if(a == 4.12)
{
    cout << "hello";
}
else
{
    cout << "bye";
}

这将显示输出为"再见4.12"

为什么?

因为默认情况下4.12是一个双精度(例如在if语句或在对变量的赋值中),但将其存储在浮点中会丢失一定的精度,因此进行比较,然后将double与float进行比较导致数字精度的微小变化——记住浮球和双打并不精确。

这里有两个教训:一个是大多数时候不应该直接比较浮点数,另一个是硬编码浮点数的默认大小和类型是双倍的。

问题是"不应该比较浮点变量和双常量"。

所以我的问题是,比较浮点变量和后面跟着"f"的浮点常量可以吗?

像这样的东西。

if(a == 4.12f)

比较float变量和后面跟着"f"的float常量可以吗?

它仍然很危险。与float/double的例子不同,a的每一个可能值都可能失败,实际上a中有一个值的a == 4.12f将是true,但根据您设置a的方式,即使您希望它与4.12f匹配,它也可能不匹配。例如:

#include <iostream>
#include <iomanip>
int main()
{
    float f = 4.14;
    f -= 0.01;
    f -= 0.01;
    std::cout << std::boolalpha << (f == 4.12f) << 'n';
}

在ideone.com上,这里输出:

false

本标准确实保证在某些情况下会使用最接近的表示,因此,如果您直接指定float a = 4.12f;,那么之后的a == 4.12f必然是true,并且§26.5.1.4保证,如果您流式传输a并将文本流式传输回另一个float,那么之后它们将比较相等。

无论如何,如果你觉得你必须依赖这样的东西,请查看Standard/docs以了解你正在考虑的具体用法。