Created
November 15, 2015 08:36
-
-
Save hamsham/67087e4ad75f07de305d to your computer and use it in GitHub Desktop.
Fast approximation of logarithms.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* testing a log function */ | |
// g++ -std=c++11 -pedantic -Wall -Werror -Wextra -W fastlog.cpp -o fastlog | |
#include <cmath> | |
#include <iomanip> | |
#include <limits> | |
#include <iostream> | |
const float TESTNUM = 2048.f; | |
/****************************************************************************** | |
* LOGARITHMS | |
******************************************************************************/ | |
/* | |
* FORWARD DECLARATIONS | |
*/ | |
template < typename type > | |
inline type fastLog2( type n ); | |
template <> | |
inline float fastLog2< float >( float n ); | |
template < typename type = float > | |
inline type fastLog( type n ); | |
template < typename type = float > | |
inline type fastLogBase( type base, type n ); | |
/* | |
* FAST LOG (BASE-2) TEMPLATE | |
*/ | |
template < typename type > | |
inline type fastLog2( type n ) { | |
float val = (float)n; | |
int* const exp = reinterpret_cast< int* >( &val ); | |
int x = *exp; | |
const int log2 = ( (x >> 23) & 255 ) - 128; | |
x &= ~(255 << 23); | |
x += 127 << 23; | |
*exp = x; | |
val = ((-1.f/3.f) * val+2.f) * val - 2.f / 3.f; | |
return (type)val + log2; | |
} | |
/* | |
* FAST LOG (BASE-2) FLOAT SPECIALIZATION | |
*/ | |
template <> | |
inline float fastLog2< float >( float n ) { | |
int* const exp = reinterpret_cast< int* >( &n ); | |
int x = *exp; | |
const int log2 = ( (x >> 23) & 255 ) - 128; | |
x &= ~(255 << 23); | |
x += 127 << 23; | |
*exp = x; | |
n = ((-1.f/3.f) * n+2.f) * n - 2.f / 3.f; | |
return n + log2; | |
} | |
/* | |
* FAST NATURAL LOG | |
*/ | |
template < typename type > | |
inline type fastLog( type n ) { | |
return fastLog2( n ) * 0.693147181f; // ln( 2 ) | |
} | |
/* | |
* FAST LOG (BASE-B) | |
*/ | |
template < typename type > | |
inline type fastLogBase( type base, type n ) { | |
return fastLog2( n ) / fastLog2( base ); | |
} | |
/****************************************************************************** | |
* MAIN() | |
******************************************************************************/ | |
int main() { | |
std::cout | |
<< std::setprecision( std::numeric_limits<float>::digits ) | |
<< "The log2 of 2048 is: " << fastLog2( TESTNUM ) << '\n' | |
<< "The log10 of 2048 is: " << fastLogBase( 10.f, TESTNUM ) << " versus: " << log10( TESTNUM ) << '\n' | |
<< "The log of 2048 is: " << fastLog( TESTNUM ) << " versus: " << log( TESTNUM ) << '\n'; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment