In Objective-C I have a timer fire every 0.1 seconds and increment a double value (seconds) by 0.1.
So it should basically keep time counting up by 1/10 of a second. When it fires it checks some if–else statements to see if time (seconds) is equal to 3, 9, 33, etc., but these are never triggered. I suppose it is because of the way doubles are represented in bits, that is the decimal is an approximation and never actually a whole number.
How can I fix this so my statements are triggered?
-(void)timeSeconds:(NSTimer*)theTimer {
seconds = seconds + 0.1;
NSLog(@"%f", seconds);
if (seconds == 3.0) {
[player pause];
[secondsTimer invalidate];
}
else if (seconds == 9){
[player pause];
[secondsTimer invalidate];
}
The floating point types cannot represent some numbers exactly, so when these are added, the error is compounded and the floating point type becomes less and less precise.
Use an integral type but represent the time difference using greater resolution, for example, use an
NSUIntegerto represent milliseconds instead of seconds, and increment by 100 instead of 0.1. Instead of comparingseconds == 3.0, you would usemilliseconds == 3000, etc.Keep in mind that timers are not fired very precisely:
You may find that when
milliseconds==9000, more than 9 seconds has actually passed (but probably not much more). There are other tools available if more precise timing is required.