Oh I know the problem - just finding a correct solution is hard.
The problem is for example visible in this matrix:
- cpp Code: Select all
matrix4 mtrouble;
mtrouble[0] = -1.1920929e-007;
mtrouble[1] = 1.1920929e-007;
mtrouble[2] = -1.0000001;
mtrouble[3] = 0.00000000;
mtrouble[4] = 1.0000001;
mtrouble[5] = -1.1920929e-007;
mtrouble[6] = 0.00000000;
mtrouble[7] = 0.00000000;
mtrouble[8] = 0.00000000;
mtrouble[9] = -1.0000001;
mtrouble[10] = -2.3841858e-007;
mtrouble[11] = 0.00000000;
mtrouble[12] = 4.0880629e-008;
mtrouble[13] = 19.588606;
mtrouble[14] = 4.1348953;
mtrouble[15] = 1.0000000;
// will have wrong result in VS
vector3df rotDeg( mtrouble.getRotationDegrees() );
The reason it goes wrong is that check I posted above is not having a large enough epsilon, so it enters the wrong code after the if. I guess we used only floats in the past and so got a larger epsilon on that check (which I got back by that cast - could also have passed it directly). And the reason why it only happens on VS and not on gcc seems to be that they support different IEEE 754 versions (VS probably still using IEEE 754-1985 which didn't define float to double casts as strict as IEEE 754-2008 - at least that's what some guys in the ##c++ channel told me when I showed up with this problem), so VS is adding a larger error on a cast.
The problem I'm having is that I don't know how large that error can be. I can just use ROUNDING_ERROR_f32 and hope it fits - maybe I'll do that as it will fix your case. But "hoping" for the correct value is rarely a good idea - just doing that could mean another person will run into this in a few months and I'll start debugging again (and this took long to debug, I spend hours just figuring out where this bug comes from). Then again I'm a little over my head right now in calculating this error - fixing this correctly would probably take me a very long time (talking days, weeks here) because I would first have to figure out how to calculate error-margins that can happen in this specific situation (not sure if that's even possible given that I have no control over the original matrix values).
Well ... I guess the only way I can do for now is to use ROUNDING_ERROR_f32 and document that I have no idea if that value is ok or not *sigh*. Probably increasing it again next time someone reports a bug there. I hope some floating point expert has one day fun calculating the correct value :-(