/*---------------------------------------------------------------------------- * * File: * eas_flog2.c * * Contents and purpose: * Fixed point square root * * * Copyright (c) 2006 Sonic Network Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *---------------------------------------------------------------------------- * Revision Control: * $Revision$ * $Date$ *---------------------------------------------------------------------------- */ #include "eas_types.h" #include "eas_math.h" #define MANTISSA_SHIFT 27 #define MANTISSA_MASK 0x0000000f #define MANTISSA_LSB_SHIFT 7 #define MANTISSA_LSB_MASK 0x000fffff #define LOG_EXPONENT_SHIFT 10 #define INTERPOLATION_SHIFT 20 #define MAX_NEGATIVE (-2147483647-1) /* log lookup table */ static const EAS_U16 eas_log2_table[] = { 0, 90, 174, 254, 330, 402, 470, 536, 599, 659, 717, 773, 827, 879, 929, 977, 1024 }; /*---------------------------------------------------------------------------- * EAS_flog2() *---------------------------------------------------------------------------- * Purpose: * Calculates the log2 of a 32-bit fixed point value * * Inputs: * n = value of interest * * Outputs: * returns the log2 of n * *---------------------------------------------------------------------------- */ EAS_I32 EAS_flog2 (EAS_U32 n) { EAS_U32 exp; EAS_U32 interp; /* check for error condition */ if (n == 0) return MAX_NEGATIVE; /* find exponent */ for (exp = 31; exp > 0; exp--) { /* shift until we get a 1 bit in bit 31 */ if ((n & (EAS_U32) MAX_NEGATIVE) != 0) break; n <<= 1; } /*lint -e{701} use shift for performance */ exp <<= LOG_EXPONENT_SHIFT; /* get the least significant bits for interpolation */ interp = (n >> MANTISSA_LSB_SHIFT) & MANTISSA_LSB_MASK; /* get the most significant bits for mantissa lookup */ n = (n >> MANTISSA_SHIFT) & MANTISSA_MASK; /* interpolate mantissa */ interp = ((eas_log2_table[n+1] - eas_log2_table[n]) * interp) >> INTERPOLATION_SHIFT; exp += eas_log2_table[n] + interp; return (EAS_I32) exp; }