I've been toying around with the algorithm to compute the length, and (believe) I've discovered a few (strange) things. The results I posted in the previous post was while generating random axis+angle rotations. So all of those quaternions were already close to being normalized (within 0.001 or so). I thought this might not be the best testing environment, so I changed it to generate random quaternions of two random types (50% of both) - both are completely random (using boost's randomizer) - the first type has a length ranging from 0.7 to 1.3, and the second type has a length ranging from 0.0001 to 1000.

With these quaternions, boost's method encounters error for about 45% of them, so apparently it is optimized to deal with nearly-normalized values (makes sense). However, I've been goofing around, toying with numbers, and I've found that if I multiply all of the squared components by the specific value **5.9292812347412109**, then multiply the resulting length by its inverse, I get no error in over 94% of all of the quaternions. I then tried using this number again with just the crazy quaternions (+/- 1000), getting 94% accuracy, and then just on nearly-normalized quaternions (+/- 0.3), getting 93% accuracy, so the quaternion values don't seem to influence it much at all.

I don't pretend to understand why its happening, and was actually hoping someone out there may be able to shed some light on it. Also, I'm wondering if this is somehow machine-specific, or if its something that can be used universally on the standard floating point model. As a total side-note, I was able to get 96% error free with the value 83.852615356445313, but I like the idea of using a smaller value better, and the improvement wasn't significant.

Here's the code I've been messing around with. I apologize in advance if, like I said, I'm accidentally rigging the results in some way, or doing something really dumb here. But I appreciate anyone testing it out to see how well it works.

real ComputeLength(real x,real y,real z,real w)
{
// square all components
x *= x;
y *= y;
z *= z;
w *= w;
// prepare crazy scaler with inverse
real mc = 5.9292812347412109f;
real mi = 1 / mc;
mi *= mi;
// compute length scaled by crazy scaler inverse, then scale back to normal
return mc * sqrt( x*mi + y*mi + z*mi + w*mi );
}

I apologize for the confusion I may have introduced. You didn't (and still haven't) posted any code, so I tried to reproduce your results and I failed.

I thought I did post all of the code you asked to see. As I said, my original normalization code literally multiplies the components of the quaternion by the inverse of its length - literally { this.Scale( 1 / sqrt(x*x + y*y + z*z + w*w) ); }, where Scale() simply multiplies the components by the scaler given. If there's something else you want to see, let me know.

The only part that you should learn from what I did is to show complete information, including code to go with what you observe, so others can reproduce what you see.

Well, I tried to post all of the code that I thought was relevant. But I'm inexperienced when it comes to battling floating point error, so I don't really know what **is** relevant. But you are free to look at any of my code you wish. Just let me know what you would like to see.

**Edited by Stephany, 08 August 2014 - 03:34 PM.**