André Fratelli
André Fratelli

Reputation: 6068

Objective-c division does not match manual calculation

Now here's a strange issue. The result for a division is different with objective-c and my manual solution. Obviously I first assumed my solution to be wrong, but either I'm missing something or... It isn't.

Here's the code:

GLfloat t = (gone - delay) / kHyAuthenticationViewControllerAnimationDuration;
NSLog(@"%f %f %f", (gone - delay), kHyAuthenticationViewControllerAnimationDuration, t);

This logs 0.017853 3.500000 3.035706. Which means that 0.017853 / 3.500000 should be 3.035706, right ??? Wrong. It actually is 0.00510085714286. The number is not that small that would give precision issues, and even so, it would probably round of to something like 0.0... Am I missing something??

Edit with the full code:

- (void)animateIn:(NSTimer*)timer
{
    NSArray *buttons = @[self.registrationButton];//, self.facebookButton, self.linkedInButton, self.twitterButton];
    NSDate *when = [timer userInfo];
    NSTimeInterval gone = [[NSDate date] timeIntervalSinceDate:when];
    NSUInteger finished = 0;

    for (int it=0 ; it < [buttons count] ; ++it) {

        UIButton *button = [buttons objectAtIndex:it];
        GLfloat toValue = self.registrationView.frame.origin.y + 37 + button.frame.size.height * it + 10 * it;
        GLfloat fromValue = toValue + self.view.frame.size.height;
        GLfloat delay = kHyAuthenticationViewControllerAnimateInDelayFactor * it;
        CGRect frame;

        // Have we waited enough for this button?
        if (gone >= delay) {

            // Use the timing function
            GLfloat t = (gone - delay) / kHyAuthenticationViewControllerAnimationDuration;
            NSLog(@"%f %f %f", (gone - delay), kHyAuthenticationViewControllerAnimationDuration, t);

//            t = [HyEasing easeOutBounce:t];

            // Is the animation finished for this button?
            if (t >= 1.0f) {
                t = 1.0f;
                ++finished;
                continue;
            }

            // Compute current displacement
            GLfloat displacement = fabs(toValue - fromValue);
            GLfloat y = toValue + displacement * (1.0f - t);

            // Create the frame for the animation
            frame = CGRectMake(button.frame.origin.x, y, button.frame.size.width, button.frame.size.height);
        }

        // Make sure the button is at its initial position
        else frame = CGRectMake(button.frame.origin.x, fromValue, button.frame.size.width, button.frame.size.height);

        [button setFrame:frame];
    }

    if (finished == [buttons count]) {
        [timer invalidate];
    }
}

Upvotes: 2

Views: 75

Answers (1)

Ken Thomases
Ken Thomases

Reputation: 90531

kHyAuthenticationViewControllerAnimationDuration is a preprocessor macro with a compound expression that's not enclosed in parentheses. So, when it was incorporated into another compound expression, the terms of kHyAuthenticationViewControllerAnimationDuration associated more strongly with terms of the containing expression than with each other, changing the order of operations.

That is,

(gone - delay) / kHyAuthenticationViewControllerAnimationDuration

expanded to:

(gone - delay) / 0.5f + 3

which evaluated like:

((gone - delay) / 0.5f) + 3

Upvotes: 3

Related Questions