为什么我们在浮点值比较中得到故障比较结果

时间:2013-03-16 05:33:04

标签: iphone floating-point

我从服务器获取r,g,b值都是整数值,我将这些整数值转换为以这种方式浮动

int a;
float b=a;

然后我将这些浮点值除以255.0f后再与0.51690相比,但实际上我得到的比较结果是0而不是1。

这里的r,g,b值是int,appdelegate.userRed,appdelegate.userGreen,appdelegate.userBlue是浮点数。

appdelegate.userRed=r;
appdelegate.userGreen=g;
appdelegate.userBlue=b;
NSLog(@"r is %d",r);
  

结果:2013-03-16 10:56:33.488 * [2407:14003] r是128

float red=appdelegate.userRed/255.0;
float green=appdelegate.userGreen/255.0;
float blue=appdelegate.userBlue/255.0;
NSLog(@"red is %f",red);
  

2013-03-16 10:56:35.642 * [2407:14003]红色是0.501961

    NSLog(@"comparision is %d",(red==0.501961));
  

2013-03-16 10:57:33.743 ** [2407:14003]比较为0

2 个答案:

答案 0 :(得分:1)

对于浮点比较,我们必须在值的末尾使用f或F.下面的

NSLog(@"comparision is %d",(red==0.501961F));

没有f意味着它是单精度浮点数而不是双精度双精度浮点数。

来自C99标准:

An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has type float.

用于浮点比较,

int compare_float(float f1, float f2)
{
    float precision = 0.00001;
    if (((f1 - precision) < f2) && 
        ((f1 + precision) > f2))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

答案 1 :(得分:1)

您的代码首先计算appdelegate.userRed/255.0,其中appdelegate.userRed为128.数学上,这是128/255。但是,由于您在计算机中使用浮点运算,因此计算机必须返回可在该浮点系统中表示的值,而不是精确的数学值。在这种情况下,128/255.0的类型为double,最接近128/255的double为0.5019607843137254832299731788225471973419189453125。

然后您的代码会将该值分配给red。由于redfloat,因此该值会转换为float。同样,该值必须四舍五入。最接近0.5019607843137254832299731788225471973419189453125的float值是0.501960813999176025390625。

然后您将red0.501961进行比较。编译器将源文本0.501961转换为最接近的值,表示为double,即0.50196099999999999052846533231786452233791351318359375。

由于0.501960813999176025390625不等于0.50196099999999999052846533231786452233791351318359375,因此比较返回false。

很难为您提供替代方案,因为您没有解释为什么要进行此比较。如果您只想检查像素的float值是否是将整数128转换为float除以255的直接结果,那么我建议您使用red==128/255.f。 (您可能还希望将appdeletegate.userRed/255.0更改为appdelegate.userRed/255.f,以便您在名义上使用float,而不是double整个代码。)

但是,如果您正在做更多涉及浮点运算的事情,还有其他注意事项。特别是,如果float值不是此转换的直接结果,除以255但是是附加算术的结果,则该值可能包含其他舍入误差,并将其直接与{{{ 1}}不会产生预期的结果。