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

时间:2014-06-02 19:43:43

标签: c floating-point comparison

案例1

float a = 0.6;

if (a < 0.6)
{
    printf("c");
}
else
{
    printf("c#");
}

输出c#

案例2

float a = 0.9;

if (a < 0.9)
{
    printf("c");
}
else
{
    printf("c#");
}

输出c

现在问题是为什么?

3 个答案:

答案 0 :(得分:7)

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

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

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

在每种情况下,无法精确表示的小数部分四舍五入到最接近的double表示文字。它被舍入到浮点数以分配给a,它在圆形到最近的规则下可能略小或略大于双精度,或者如果双精度的二进制表示有很多,则可能完全相同尾随零。

答案 1 :(得分:0)

简短回答:浮点数无法用二进制表示法精确表示,即使它们具有十进制的终止定义。这意味着将浮点数与另一个浮点数(假设相等的浮点数)进行比较并不能保证两种方式,一切都取决于架构和该架构上浮点数的表示。

答案 2 :(得分:0)

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

float a = 0.6f;

if (a < 0.6f)
{
    printf("c");
}
else
{
    printf("c#");
}

错误实际上与准确性问题无关,而且与类型提升有关。这相当于将300推入char,然后将结果与实数300进行比较。当你第一次推入它时,值被截断以适应较小的类型,并且在比较期间它被提升回更大的类型。

修改

每个人在这里谈论的准确性问题都是一个不同的现象。您可以使用布尔表达式(4.0*3.0 == 2.0*6.0)清楚地看到它显示两个术语都是12.03.06.0的不同截断可以使这两个算术表达式不同。但是,如果您编写了表达式(3.0*5.0 == 3.0*5.0),那么对于任何符合标准的处理器来说,这始终是正确的。(对于包括intel在内的许多处理器,您可以操纵配置,使它们不符合IEEE浮点数标准)