在C中比较浮点数和双精度浮点数

4
我使用以下代码在C语言中比较一个浮点变量和一个双精度变量。
int main()
{
    float f = 1.1;
    double d = 1.1;

    if(f==d)
        printf("EQUAL");

    if(f < d)
        printf("LESS");

    if(f > d)
        printf("GREATER");

    return 0;
}

我正在使用在线C编译器这里编译我的代码。
我知道对于循环小数,EQUAL永远不会被打印出来。然而我期望的应该是LESS,因为double应该有更高的精度,因此应该比float更接近实际值1.1。据我所知,在C中当你比较float和double时,float的尾数被扩展为与double相同的尾数,而那个被扩展的值应该总是更小的。
然而在所有情况下GREATER被打印出来。我是否漏掉了什么?

也许可以这样说:float -> 1.09999999999,double -> 1.1……float 并不总是四舍五入到更高的值,而是最接近可表示的值。 - Alberto Sinigaglia
如果四舍五入后的值已经更高,您可以添加任意多个零。它不会变小。 - Gerhardh
2
π保留五位小数为3.1416。π保留十位小数为3.141592654。因此,五位数的π大于十位数的π。当源代码中的十进制数转换为"float"或"double"时,它会四舍五入到最接近的可表示值,而不是截断。(至少通常是这样的;根据语言标准、实现质量等情况可能会有例外。) - Eric Postpischil
@EricPostpischil 是的,那就是我犯的错误,我以为浮点数值会被截断而不是四舍五入。谢谢你的回答 :) - Rijul Ganguly
关于代码 float f = 1.1;,这是试图将一个 double 字面量压缩到一个 float 变量中。更好的做法是使用 float f = 1.1f;。请注意末尾的 f,它将字面量转换为 float 值。 - user3629249
2个回答

9
离1.1最近的float精度为1.10000002384185791015625,二进制等效值为1.00011001100110011001101。
离1.1最近的double精度为1.100000000000000088817841970012523233890533447265625,二进制等效值为1.0001100110011001100110011001100110011001100110011010。
把这两个二进制数排成一列:
1.00011001100110011001101
1.0001100110011001100110011001100110011001100110011010

用于将double转换为float时,前几位被截断的二进制数为11001100,大于一半,因此转换为float后向上舍入,使最低有效位变为11001101。这种舍入导致浮点数的最显著差异是,在一个双精度浮点数中为0的二进制位上,浮点数中有一个1。无论低位的数值在浮点数扩展至双精度时是否为零,在双精度浮点数中都是非零的,因此浮点数大于双精度浮点数。


6
如果您在声明这两个变量后添加以下2行代码:
printf("%.9g\n", f);
printf("%.17g\n", d);

您将获得以下输出:
1.10000002                                                                                                                  
1.1000000000000001

因为精度的缘故,我们可以很容易地看出float大于double,因此打印GREATER没有问题。


是的,你在这里确实是正确的。但我认为当与double比较时,float的尾数总是被零扩展为double的尾数?这不是它的工作方式吗? - Rijul Ganguly
@RijulGanguly 如果你将1.10000002进行零扩展,会得到1.1000000200000000,它仍然大于1.1000000000000001,对吧?(或者我错过了什么?) - Steve Summit
@SteveSummit 没错,从这个意义上来说,这非常简单明了。 - David
2
“由于精度问题,float 比 double 更大”这种说法有点误导。由于精度不同,值也会不同。在这种情况下,float 值更大。对于约一半的非精确小数,double 值会更大。 - chux - Reinstate Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接