Hehe Charles,
Actually moving all the constants out of function bodies really did the trick! In fact, Oxygen's
my_log now runs even a little bit faster than in DynC!
(see attachment 1)As for
sqrt, I wasn't so much after it though I'm glad I added it too to my palette. I was after its reciprocal counterpart that's in fact a fundamental corner stone of all 3D trigonometry -- the inverse square root, or
1 / sqrt. The canonical function that I'm using was designed by
John Carmack for his immortal
Quake III shooter. Here's its original code with the author's notes intact:
(move const float threehalfs = 1.5F; to the global space if your C compiler doesn't regard the const qualifier as a directive to do it automatically)float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}Surprisingly, the accuracy of approximation with just one Newton step (called "iteration" here) is not worse than 0.175% in the entire range of acceptable values! And it is significantly faster too than simple
1 / sqrt or
1 / my_sqrt.
(see attachment 2)These approximations are perfectly acceptable in present-day 3D. In fact
a lot of modern video games use half-floats (2-byte floating-point values) for their geometry, texturing, and light including my favorite
Resident Evil 4 thru
6 shooter.
(come look John, she's starring the movies based on this game):Thanks for taking interest in the topic, Charles!
.