# Fast log2¶

• Author or source: Laurent de Soras
• Created: 2002-02-10 12:31:20
code
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13``` ```inline float fast_log2 (float val) { assert (val > 0); int * const exp_ptr = reinterpret_cast (&val); int x = *exp_ptr; const int log_2 = ((x >> 23) & 255) - 128; x &= ~(255 << 23); x += 127 << 23; *exp_ptr = x; return (val + log_2); } ```

## Comments¶

```And here is some native Delphi/Pascal code that
does the same thing:

function fast_log2(val:single):single;
var log2,x:longint;
begin
x:=longint((@val)^);
log2:=((x shr 23) and 255)-128;
x:=x and (not(255 shl 23));
x:=x+127 shl 23;
result:=single((@x)^)+log2;
end;

Cheers

Toby

www.tobybear.de
```
```instead of using this pointer casting expressions one can also use a enum like this:

enum FloatInt
{
float f;
```
```instead of using this pointer casting expressions one can also use a enum like this:

enum FloatInt
{
float f;
int l;
} p;

and then access the data with:

p.f = x;
p.l >>= 23;

Greetings, Henry
```
```Sorry :

didnt mean enum, ment UNION !!!
```
• Date: 2005-10-18 10:03:47
• By: Laurent de Soras
```More precision can be obtained by adding the following line just before the return() :

val = map_lin_2_exp (val, 1.0f / 2);

Below is the function (everything is constant, so most operations should be done at compile time) :

inline float map_lin_2_exp (float val, float k)
{
const float a = (k - 1) / (k + 1);
const float b = (4 - 2*k) / (k + 1);     // 1 - 3*a
const float c = 2*a;
val = (a * val + b) * val + c;

return (val);
}

You can do the mapping you want for the range [1;2] -> [1;2] to approximate the function log(x)/log(2).
```
• Date: 2005-10-18 10:05:48
• By: Laurent de Soras
```Sorry I meant log(x)/log(2) + 1
```