意外的浮点比较

时间:2012-07-18 12:14:50

标签: c floating-point precision floating-accuracy

请考虑以下代码:

#include<stdio.h>
#define k 0.7
#define p 0.5
int main()
{
    float a=k,b=p;
    double aa=k;
    if(a<k)
    {
         if(b<p) printf("2 is right");    
         else      printf("1 is right");
    }
    else printf("0 is right");
    printf("\n");
    if(a>k)
    {
         if(b<p) printf("2 is right");    
         else      printf("1 is right");
    }
    else printf("0 is right");
    return 0;
}

将此视为this问题的第二部分,这里的理解是浮点常量的双精度值(当表示为数字常量时加倍)在转换为相应的浮点值时丢失。特殊值是X.5和X.0。但我观察到以下结果:

Input           Output
K=0.1 to 0.4        0 is right
                    1 is right

K=0.5               0 is right
                    1 is right

K=0.6               0 is right
                    1 is right

K=0.7               1 is right
                    0 is right

K=0.8               0 is right
                    1 is right

K=0.9               1 is right
                    0 is right

K=8.4               1 is right
                    0 is right

为什么这种酷儿行为?为什么只有少数浮点值显示此属性?我们不能假设float精度值总是小于而不是double精度值吗?我们如何解释这种行为?

1 个答案:

答案 0 :(得分:2)

  

我们不能假设float精度值总是小于double精度值吗?

不是真的,它们可能都具有相同的精度。您可以假设double的范围和精度不小于float的范围和精度。

但是,出于所有实际目的,这是一个有利可图的赌注,double有53位精度而float有24位。double有11位指数,{{1 8位。

因此,忽略异国情调的架构,float精度较低,范围小于float,每个double值可表示为float,但反之亦然。因此,从doublefloat的转换是保值的,但从double转换为double会改变所有需要超过24位精度的值。

通常通过以下列方式将float值的有效位四舍五入为24位精度来执行强制转换(对于float范围内的值):

  • 如果有效数据的25 th 最高有效位为0,则有效数字被截断(该值向零舍入)
  • 如果25 th 最高有效位为1,并且并非所有低有效位都为0,则该值从零开始舍入(有效数被截断,然后是有效值的值)位已添加)
  • 否则,有效数是四舍五入的,因此24 th 最重要的位为零,在一半的情况下从零开始向零舍入到零。

您无法通过查看小数点扩展来预测doubledouble是否会增加或减少该值,除非在少数情况下您可以看到该值将保持不变。重要的是二元扩展。