小于(<)比较浮动与c中的if语句

Dio*_*ios 3 c floating-point comparison

情况1

float a = 0.6;

if (a < 0.6)
{
    printf("c");
}
else
{
    printf("c#");
}
Run Code Online (Sandbox Code Playgroud)

输出c#

案例2

float a = 0.9;

if (a < 0.9)
{
    printf("c");
}
else
{
    printf("c#");
}
Run Code Online (Sandbox Code Playgroud)

输出c

现在问题是为什么?

Pat*_*han 8

我假设float是IEEE 754 32位二进制文​​件,double是IEEE 754 64位二进制文​​件.

最接近的0.6,即文字的实际值,是0.59999999999999997779553950749686919152736663818359375.将其转换为浮动的结果为0.60000002384185791015625,略大.

最接近0.9的是0.90000000000000002220446049250313080847263336181640625.将其转换为浮动的结果为0.89999997615814208984375,略小.

在每种情况下,无法精确表示的小数部分四舍五入到最接近的double表示文字.它被舍入到浮点数以进行赋值a,在圆形到最近的规则下可能比double更小或略大,或者如果double的二进制表示具有大量尾随零,则甚至可能完全相同.


Ste*_*Cox 0

将整个事情更改为仅使用单个文字,并且它应该始终有效

float a = 0.6f;

if (a < 0.6f)
{
    printf("c");
}
else
{
    printf("c#");
}
Run Code Online (Sandbox Code Playgroud)

该错误实际上与准确性问题无关,而与类型提升有关。这有点相当于推300入 a char,然后将结果与实际整数进行比较300。当您第一次将其推入时,该值会被截断以适合较小的类型,并且在比较过程中它会被提升回较大的类型。

编辑

大家在这里谈论的准确性问题是不同的现象。您可以通过布尔表达式(4.0*3.0 == 2.0*6.0)清楚地看到它,这两个术语都是,但是和12.0的不同截断可以使这两个算术表达式不同。然而,如果您编写了表达式,则对于任何符合标准的处理器来说,这始终是正确的。(注意,对于包括英特尔在内的许多处理器,您可以操纵配置,使它们不符合 IEEE 浮点标准)3.06.0(3.0*5.0 == 3.0*5.0)