Files

92 lines
3.1 KiB
C
Executable File

/*------------------------------------------------------------------------------
Copyright 2016 Sony Semiconductor Solutions Corporation
Last Updated : 2016/06/24
Modification ID : 3b74e280b7ad8ce430b6a9419ac53e8f2e3737f9
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Includes
------------------------------------------------------------------------------*/
#include "sony_math.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
#define MAX_BIT_PRECISION 5
#define FRAC_BITMASK 0x1F /**< Depends upon MAX_BIT_PRECISION. */
#define LOG2_10_100X 332 /**< log2 (10) */
#define LOG2_E_100X 144 /**< log2 (e) */
/*------------------------------------------------------------------------------
Statics
------------------------------------------------------------------------------*/
/**
@brief Look up table for decimal portion of log2 calculation.
*/
static const uint8_t log2LookUp[] = {
0, /* 0 */ 4, /* 0.04439 */
9, /* 0.08746 */ 13, /* 0.12928 */
17, /* 0.16993 */ 21, /* 0.20945 */
25, /* 0.24793 */ 29, /* 0.28540 */
32, /* 0.32193 */ 36, /* 0.35755 */
39, /* 0.39232 */ 43, /* 0.42627 */
46, /* 0.45943 */ 49, /* 0.49185 */
52, /* 0.52356 */ 55, /* 0.55249 */
58, /* 0.58496 */ 61, /* 0.61471 */
64, /* 0.64386 */ 67, /* 0.67246 */
70, /* 0.70044 */ 73, /* 0.72792 */
75, /* 0.75489 */ 78, /* 0.78136 */
81, /* 0.80736 */ 83, /* 0.83289 */
86, /* 0.85798 */ 88, /* 0.88264 */
91, /* 0.90689 */ 93, /* 0.93074 */
95, /* 0.95420 */ 98 /* 0.97728 */
};
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
uint32_t sony_math_log2 (uint32_t x)
{
uint8_t count = 0;
uint8_t index = 0;
uint32_t xval = x;
/* Get the MSB position. */
for (x >>= 1; x > 0; x >>= 1) {
count++;
}
x = count * 100;
if (count > 0) {
if (count <= MAX_BIT_PRECISION) {
/* Mask the bottom bits. */
index = (uint8_t) (xval << (MAX_BIT_PRECISION - count)) & FRAC_BITMASK;
x += log2LookUp[index];
}
else {
/* Mask the bits just below the radix. */
index = (uint8_t) (xval >> (count - MAX_BIT_PRECISION)) & FRAC_BITMASK;
x += log2LookUp[index];
}
}
return (x);
}
uint32_t sony_math_log10 (uint32_t x)
{
/* log10(x) = log2 (x) / log2 (10) */
/* Note uses: logN (x) = logM (x) / logM (N) */
return ((100 * sony_math_log2 (x) + LOG2_10_100X / 2) / LOG2_10_100X);
}
uint32_t sony_math_log (uint32_t x)
{
/* ln (x) = log2 (x) / log2(e) */
return ((100 * sony_math_log2 (x) + LOG2_E_100X / 2) / LOG2_E_100X);
}