The iPhone’s atan2
September 20th, 2009
An interesting code snippet:
y = -0.79999995231628417968750000000000000000000000000000f; x = 0.60000008344650268554687500000000000000000000000000f; NSLog(@"%.50f", atan2f(y, x));
Why so interesting? Well, it’s interesting because the iPhone simulator and the iPhone device produce a different result for atan2f(y, x).
iPhone simulator:
-0.92729508876800537109375000000000000000000000000000
iPhone:
-0.92729514837265014648437500000000000000000000000000
(For non-programmers: atan2f is a function that computes the arc tangent of two variables.)
Have you fallen off your chair? No? Right, well anyway, although I’m confident that there’s a compiler flag that will bring the two platforms into agreement, I couldn’t find one. Hint: it’s not -ffloat-store. My current suspicion is that this problem stems from “y” and “x” being stored in two registers. This would give them extra precision. That is, more precision than the IEEE prescribes.
Ok, but who cares, right? Well, say you’re developing a physics based puzzle game. For the sake of argument, we’ll call this game “Pocketball”. So in Pocketball, you’ve got these objects that bounce around the world, obeying the laws of physics, more or less. Months into the development of Pocketball, you discover that the physics is performing very slightly differently on the device as it is on the simulator. Specifically, objects bounce off other objects at angles that are very slightly different between the two platforms. These “very slight” differences eventually become big differences and, in the end, the configuration of the world is completely different.
So what can be done? The most important thing is just to be aware of this. Like I said earlier, I’m yet to discover a compiler flag that resolves the discrepancy. So for the time being, just add this fact to the list of reasons why you always test your software on the device and not solely depend on how it behaves in the simulator.