accumulated error from incremental turns about local axes. think flight sim, 3 degrees rotational freedom. orientation can be stored as Eulers, matrix, quaternion, direction vector and roll, etc.
pixel perfect means i'm at some arbitrary orientation, say 17 degrees x rotation, 23 degrees y rotation, 38 degrees z rotation (left hand system). now i do a 360 around my local y axis, in 3600 steps of 0.1 degree each. when i'm done turning, i "should" have the same pixel in the center of my screen.
This is generally not possible with any representation, for the simple reason that 0.1° ≈ 0.0062831853, which is not representable using IEEE 754 math. Also, its cosine is not representable. Therefore, error must occur, and error must accumulate.
Quaternion multiplication has fewer operations, and quaternions have fewer components, so there is less opportunity for error to accumulate, but still they cannot be "perfectly accurate" if you combine a thousand of them. But even if you only keep adding very small values to a single float, and convert the accumulated value, you will see error accumulation.
The most accurate solution to your specific problem (doing 1000 little rotations around the y axis, or some axis) would be to use fixed point math to store the intermediate angles of rotation around a vector (in that case [0,1,0]), and convert these to either matrix or quaternion at ever frame just for the purpose of doing the model transform when rendering. Adding up the integer 1 a thousand times gives exactly 1,000 (with very few, entirely irrelevant exceptions!), and doing 1,000 or 100,000 little rotations will be "pixel perfect", except for unavoidable rounding errors.
The unavoidable rounding errors are the ones occuring during the calculation of the cosine and due to the cosine usually not being exactly representable as float, and rounding errors that occur while the GPU does the transform, on which you have little or no influence.
Fixed point works perfectly for rotating around any single axis, but for combining rotations around a large of different vectors it isn't too useful (that's another problem though, and I don't think there exists a precise solution for this).
Fixed-point has the apparent disadvantage of not being able to rotate smaller steps than some previously chosen minimum, but you cannot do math with "normal sized" and "some arbitrarily small" float values, either. In fact, you can -- it just doesn't work as you expect (which is much worse, in my opinion). So, this really isn't a disadvantage, but an advantage.
If you choose something like 1/1,000 or 1/10,000 (or some power of two, such as 1/220 to allow the compiler to use shifts), it should be accurate enough for most people (nobody can possibly tell a difference of 1/1,048,576°).
Edited by samoth, 01 April 2013 - 11:03 AM.