-1

I am getting the r,g,b values from the server all are integer values and I am convering those integer values to float in this manner

int a;
float b=a;

Then i am dividing those float values with 255.0f after that am comparing with 0.51690 but here actually the comparision results what i am getting is 0 instead of 1.

Here r,g,b values are int and appdelegate.userRed,appdelegate.userGreen, appdelegate.userBlue are floats.

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

Result: 2013-03-16 10:56:33.488 *[2407:14003] r is 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] red is 0.501961

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

2013-03-16 10:57:33.743 **[2407:14003] comparision is 0

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Naresh
  • 363
  • 1
  • 18
  • 1
    There is rally no `==` for float types in any language... Check out http://stackoverflow.com/questions/2100490/floating-point-inaccuracy-examples and http://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal for top answers... – Alexei Levenkov Mar 16 '13 at 05:37
  • 2
    @AlexeiLevenkov: This is a commonly misunderstand aspect of floating-point. The `==` operation works perfectly well in floating-point and in fact has no rounding errors. Rounding errors actually occur in other operations. While you might argue that you cannot use `==` because of prior operations with rounding errors, this is incorrect or misleading for two reasons. One, you can use `==` if you design your software appropriately. Two, the rounding errors affect essentially all operations, not just `==`. E.g., `sqrt` also fails if rounding errors have made the value negative. – Eric Postpischil Mar 16 '13 at 11:24
  • @EricPostpischil, example of "appropriate design" may be useful. I'm not sure I get your idea here... – Alexei Levenkov Mar 17 '13 at 03:32
  • @AlexeiLevenkov: Sorry, it depends on context, and any detailed answer is too long for a comment. There are volumes written about floating point, such as [*Handbook of Floating-Point Arithmetic*](http://amzn.com/081764704X). There is no a single explanation of when to use `==` any more than there a single explanation of when to use `+` or `sqrt`. Simply understand that `==` **works**; it is not testing for equality that is a problem but rather rounding errors that occur in other operations. To use floating-point well, one must understand those errors and how to control, avoid, or use them. – Eric Postpischil Mar 17 '13 at 13:16
  • @EricPostpischil, You have perfectly valid point of view... I guess my definition of "works" is simply different from yours (produces result on would expect from day-to-day life vs. behaves exactly as specified). I consider operator that requires reading books about to be "not really useful" (i.e. "+" behaves much more reasonable). – Alexei Levenkov Mar 17 '13 at 20:28
  • @AlexeiLevenkov: Unlike `==`, `+` does not work. `==` is mathematically correct; it returns true if and only if its operands are equal. However, `+` is broken: For most inputs, it returns a mathematically incorrect result. E.g., `2**64+1` returns 2**64, which has completely lost one of the operands. Even adding, say, the representable value nearest 1/3 to 1 returns an incorrect result. This is why the common advice about `==` is wrong: People are blaming the wrong thing, because `==` is one of the few operations that does its job perfectly. It is the other operations people must watch out for. – Eric Postpischil Mar 17 '13 at 23:09

2 Answers2

1

for Floating point comparison we must use f or F at the end of the value .like below

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

without f means it's a single-precision float rather than a double precision double.

From the C99 standard:

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

for floating point comparison,

int compare_float(float f1, float f2)
{
    float precision = 0.00001;
    if (((f1 - precision) < f2) && 
        ((f1 + precision) > f2))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
Balu
  • 8,470
  • 2
  • 24
  • 41
  • hi sunny really thanks a lot for your reply. I tried in the way what you said but still i am getting the 0 as a comparision result.please help me if you have any info beyond this... – Naresh Mar 16 '13 at 06:15
  • hi sunny thanks a lot :) your code resolved the issue. May i know why we have to do this much for float value comparision.thanks once again. – Naresh Mar 16 '13 at 10:23
1

Your code first computes appdelegate.userRed/255.0 where appdelegate.userRed is 128. Mathematically, this is 128/255. However, since you are using floating-point arithmetic in a computer, the computer must return a value that is representable in that floating-point system rather than the exact mathematical value. In this case, 128/255.0 has type double, and the double that is closest to 128/255 is 0.5019607843137254832299731788225471973419189453125.

Then your code assigns that value to red. Since red is a float, the value is converted to float. Again, the value must be rounded. The float value that is nearest to 0.5019607843137254832299731788225471973419189453125 is 0.501960813999176025390625.

Then you compare red to 0.501961. The compiler converts the source text 0.501961 to the nearest value representable as a double, which is 0.50196099999999999052846533231786452233791351318359375.

Since 0.501960813999176025390625 is not equal to 0.50196099999999999052846533231786452233791351318359375, the comparison returns false.

It is difficult to suggest alternatives for you because you have not explained why you are making this comparison. If you merely wish to check whether the float value of a pixel is the direct result of converting an integer 128 to float by dividing by 255, then I suggest you use red==128/255.f. (You may also wish to change appdeletegate.userRed/255.0 to appdelegate.userRed/255.f so that you are nominally using float, rather than double throughout your code.)

However, if you are doing anything more involved with floating-point arithmetic, there are additional considerations. In particular, if a float value is not the direct result of this conversion by dividing by 255 but is the result of additional arithmetic, then it is likely the value will contain additional rounding errors, and comparing it directly to 128/255.f will not produce the desired result.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Nice explanation thanks a lot to spend ur valuable time for giving this much of clear explanation. Thanks a lot Eric. – Naresh Mar 16 '13 at 17:35