Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
 MacRumors Forums Weird If Statement behaviour using Float and <= sign

 Dec 25, 2008, 04:52 AM #1 roeik macrumors member   Join Date: Dec 2008 Weird If Statement behaviour using Float and <= sign Hi, I wrote the following function using if statements. Everything works fine except for two bugs. If ct is equal to .04, .08, 0.7, or 0.9 the function returns the value in the previous return statement. So for example, when ct is .04 it returns 0 and not 1. The same weird behavior occurs with the numbers I specified above, but works well with all the other numbers. Any suggestions? Thanks. - (int) sizeIndexfloat) ct { NSLog(@"%f", ct); if (ct > 0 && ct < 0.04) return 0; if (ct >= 0.04 && ct < .08) return 1; if (ct >= 0.08 && ct < .15) return 2; if (ct >= 0.15 && ct < .18) return 3; if (ct >= 0.18 && ct < .23) return 4; if (ct >= 0.23 && ct < .3) return 5; if (ct >= 0.3 && ct < .4) return 6; if (ct >= 0.4 && ct < .5) return 7; if (ct >= 0.5 && ct < .7) return 8; if (ct >= 0.7 && ct < .9) return 9; if (ct >= 0.9 && ct < 1) return 10; if (ct >= 1 && ct < 1.5) return 11; if (ct >= 1.5 && ct < 2) return 12; if (ct >= 2 && ct < 3) return 13; if (ct >= 3 && ct < 4) return 14; if (ct >= 4 && ct < 5) return 15; if (ct >= 5 && ct < 10) return 16; if (ct >= 10) return 17; else return -1; } 0
 Dec 25, 2008, 05:28 AM #2 Allanist macrumors newbie   Join Date: Mar 2007 You're mixing floats and doubles. Code: ```float f = 0.04; double d = 0.04; if (f==d) { //This is never true }``` Code: ```if (ct > 0 && ct < 0.04f) return 0; if (ct >= 0.04f && ct < .08f) return 1; ...``` 0
 Dec 25, 2008, 06:56 AM #3 roeik Thread Starter macrumors member   Join Date: Dec 2008 thanks 0
 Dec 25, 2008, 11:53 AM #4 toddburch macrumors 6502a   Join Date: Dec 2006 Location: Katy, Texas Note that your logic is a bit verbose. This is a simplified version that gives you the same functionality, but less code. Code: ```- (int) sizeIndex: (float) ct { NSLog(@"%f", ct); if (ct > 0 && ct < 0.04) return 0; if (ct < .08) return 1; if (ct < .15) return 2; if (ct < .18) return 3; if (ct < .23) return 4; if (ct < .3) return 5; if (ct < .4) return 6; if (ct < .5) return 7; if (ct < .7) return 8; if (ct < .9) return 9; if (ct < 1.0) return 10; if (ct < 1.5) return 11; if (ct < 2.0) return 12; if (ct < 3.0) return 13; if (ct < 4.0) return 14; if (ct < 5.0) return 15; if (ct < 10.0) return 16; if (ct >= 10) return 17; return -1; }``` 0
 Dec 25, 2008, 02:04 PM #5 savar macrumors 68000     Join Date: Jun 2003 Location: District of Columbia You can't use the equality comparision (==, <=, or >=) with floating point numbers. (In most languages, float and double are both floating point types, just with differing degrees of precision.) The fact that most languages will compile code like this only adds to the confusion; you'll get the correct result for some cases, but it won't work in others. http://en.wikipedia.org/wiki/Floatin...uracy_problems __________________ Mehce 0
 Dec 25, 2008, 02:14 PM #6 blueillusion macrumors member   Join Date: Aug 2008 if you are going to use comparison operators with floats and doubles, consider setting a threshold. 0
Dec 25, 2008, 02:17 PM   #7
savar
macrumors 68000

Join Date: Jun 2003
Location: District of Columbia
Quote:
 Originally Posted by Allanist You're mixing floats and doubles. Code: ```float f = 0.04; double d = 0.04; if (f==d) { //This is never true }```
This is true, but misleading. You can compare floats and doubles. It's not the type that matters, its the content of the variable. Consider the following:
Code:
```/Users/mehaase \$ cat test.c
#import <stdio.h>

int main(int argc, char *argv) {
float f=.25;
double d=.25;
if (f==d)
printf("equal\n");
else
printf("not equal\n");
}

/Users/mehaase \$ gcc test.c -o test
/Users/mehaase \$ ./test
equal```
Your example doesn't work because the number you picked (.4) is a repeating number when converted to binary representation. Because it repeats infinitely, the differing precision of float and double result in slightly different floating point numbers. (As an example, is 1/3 == .333 or is 1/3 == .333333?)

In my example, .25 is a very simple fraction when represented in binary (1/2, 1/4, 1/8 are all simple fractions in binary because the denominator is a power of two). Therefore, the differences in precision between float and double don't make a difference.

To the OP: if you're a CS student or a professional developer, you really need to learn this stuff. If you're just a hobbyist, then just keep in mind that floating point numbers are trickier than they seem and avoid them when possible.
__________________
Mehce
0
 Dec 25, 2008, 02:23 PM #8 lee1210 macrumors 68040     Join Date: Jan 2005 Location: Dallas, TX Posting from my phone, so no links, but google "machine delta", and use it. This is essentially what savar and blueillusion were indicating. Since machines use a different number system than we are used to using to express things, methods of approximation had to be developed. IEEE-734 is the method that is most commonly used. Essentially, every mathmatical operation you perform on a float accumulates errors, which can eventually cause significant errors. This is obviously worse with 32-bit floating point numbers than 64-bit, simply because of lower possible precision. You're dealing with very few significant digits. You may be able to just deal with integers that are 100x larger than the real values you are dealing with. Good luck! -Lee 0
Dec 25, 2008, 05:35 PM   #9
Allanist
macrumors newbie

Join Date: Mar 2007
Quote:
 Originally Posted by savar This is true, but misleading. You can compare floats and doubles. It's not the type that matters, its the content of the variable...
I never said they can't be compared, I was just showing a case where OP's logic fails, without diving too deep into theory. But I agree my example was misleading.
And I think your "1/3 example" is a good way of explaining the reason behind this "anomaly".
0
 Dec 25, 2008, 06:20 PM #10 lazydog macrumors 6502a   Join Date: Sep 2005 Location: Cramlington, UK This is a subtle point but worth pointing out I think. In expressions containing mixed precision, the compiler always promotes the lower precision values to the higher precision type. So, when evaluating the if statement expression:- Code: `if (ct > 0 && ct < 0.04)` ct is first promoted to a double value and then compared to the (double) value 0.04. If the compiler took the alternative approach to resolving such cases, ie de-promote 0.04 to a float, then all would have been fine in the original code. b e n 0

 MacRumors Forums

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is Off Forum Rules