Goeff Probert
Compute signal power with fixed-point calculators
Embedded Systems Programming
October, 2003

Listing 1: Fixed-point signal level calculator

 #define MAX_TERM 27 #define SCALE 131072 // 2^17
```

// LOG10_2NM1[n] = 131072 * 100 * 10 * log10((2^n)/(2^n-1))      n >= 1
int32_t const LOG10_2NM1[MAX_TERM] =
{
```
 0, 39456604, 16375970, 7601120, 3673781, 1807258, 896457, 446464, 222794, 111288, 55617, 27802, 13899, 6949, 3474, 1737, 869, 434, 217, 109, 54, 27, 14, 7, 3, 2, 1
```};

// LOG10_2N[n] = -131072 * 100 * 10 * log10(2^n)          0 <= n < 32
int32_t const LOG10_2N[] =
{
```
 0, -39456604, -78913207, -118369811, -157826414, -197283018, -236739622, -276196225, -315652829, -355109432, -394566036, -434022640, -473479243, -512935847, -552392450, -591849054, -631305657, -670762261, -710218865, -749675468, -789132072, -828588675, -868045279, -907501883, -946958486, -986415090, -1025871693, -1065328297, -1104784901, -1144241504, -1183698108, -1223154711
```};

int32_t
intLog10(uint32_t x)
{
uint32_t	  z;
int32_t	  y;
int	          k;

/*
* log10(0) = -infiniti
*/
if (x == 0) return (-2147483648);     // largest negative int32_t value

/*
* Left shift the argument until 1 <= x < 2.
*/
for (k = 0; k < 32; k++)
{
if (x & 0x80000000) break;
x <<= 1;
}

/*
* y is a function of the number of shifts just made.
*/
y = LOG10_2N[k];

/*
* Begin Knuth's log algorithm.
*/
z = x >> 1;
for (k = 1; k < MAX_TERM; )
{
if (x == 0x80000000) break;

if ((x - z) < 0x80000000)
{
z >>= 1;
k++;
}
else
{
x -= z;
z = x >> k;
y += LOG10_2NM1[k];
}
}

return (y);

}  /* intLog10() */
```
 #define M0_ALAW -159540501 // log10(((1120**2 + 2624**2)/2) << 5) #define M0_ULAW -81494089 // log10(((2207**2 + 5215**2)/2) << 5)
```
int32_t
dBm0(uint32_t avesq, int32_t m0)
{
return ((intLog10(avesq << 5) - m0) / SCALE);

}	/* dBm0() */
```