|
Author |
Topic: What's so special about 2097152.0 (Read 1608 times) |
|
brew
|
What's so special about 2097152.0
« on: Aug 19th, 2003, 4:13pm » |
|
Hi - I'm incrementing a float variable in a for loop within the loop method. I'm incrementing it by 0.1 each interation, but can't get past 2097152.0. (btw, I understand that I shouldn't be incrementing indefinately ). I'm assuming this is float's limit, but the reference says 3.40282347E+38, which is massive! I tried it in java and get the same result. Can anyone explain to me the reasons for this limit?
|
|
|
|
brew
|
Re: What's so special about 2097152.0
« Reply #1 on: Aug 19th, 2003, 10:14pm » |
|
Thing is, it happens in java too. I can't imagine it's a bug in java. I must be a limit by design, right? (btw - 2097152.0 is binary, 2^21. If that makes any difference?)
|
« Last Edit: Aug 19th, 2003, 10:15pm by brew » |
|
|
|
|
toxi
|
Re: What's so special about 2097152.0
« Reply #2 on: Aug 20th, 2003, 6:11pm » |
|
ok, looks like i have jumped the gun (once again) and made the wrong conclusion to early... i had a look at the binary representation of a float and looking at it, all becomes very obvious. as you know, float values are packed into 4 bytes. so here're my findings: Code:S|Exponent|Mantisse 0|10010011|11111111111111111111110 = 2097151.8 0|10010011|11111111111111111111111 = 2097151.9 0|10010100|00000000000000000000000 = 2097152.0 0|10010100|00000000000000000000000 = 2097152.1 0|10010100|00000000000000000000000 = 2097152.125 0|10010100|00000000000000000000001 = 2097152.125000000001* *will be rounded to 2097152.2 |
| so as you can see at 2097152.0 the exponent is changing. this however also means that you'll loose some of the number precision as you only have a limited number of bits in the mantisse to code your number. with every exponent change the precision goes down. starting at 2097152.0 this means adding 0.1 is not enough to make a difference anymore and the result will always be rounded down to 2097152.0, hence the (at first glance) odd behaviour. as you can see further, if your offset would be anything greater than 0.125 you would be able to count at least until the next exponent change at 2^22 (4194304) where the precision goes down to steps of 0.5 etc. to avoid such problems you might want to use double precision numbers instead of floats, they're slower to handle though, so use them sparingly btw. here's some code to show you the binary representation: Code:int test=Float.floatToRawIntBits((float)(2097152.12500000000001)); void setup() { showBinary(test); } void showBinary(int x) { String res=new String(); for(int i=31; i>=0; i--) { if ((i+1)%8==0) res+="|"; res+=(x>>i)&1; } println(res); } |
|
|
« Last Edit: Aug 20th, 2003, 6:16pm by toxi » |
|
http://toxi.co.uk/
|
|
|
brew
|
Re: What's so special about 2097152.0
« Reply #3 on: Aug 20th, 2003, 8:14pm » |
|
Wow! That's a great explaination. Thanks for that! *marvels at computer science weirdness
|
|
|
|
|