Skip to content

Instantly share code, notes, and snippets.

@hamsham
Created November 15, 2015 08:36
Show Gist options
  • Save hamsham/67087e4ad75f07de305d to your computer and use it in GitHub Desktop.
Save hamsham/67087e4ad75f07de305d to your computer and use it in GitHub Desktop.
Fast approximation of logarithms.
/* 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