1 /*---------------------------------------------------------------------------- 2 * 3 * File: 4 * eas_flog2.c 5 * 6 * Contents and purpose: 7 * Fixed point square root 8 * 9 * 10 * Copyright (c) 2006 Sonic Network Inc. 11 12 * Licensed under the Apache License, Version 2.0 (the "License"); 13 * you may not use this file except in compliance with the License. 14 * You may obtain a copy of the License at 15 * 16 * http://www.apache.org/licenses/LICENSE-2.0 17 * 18 * Unless required by applicable law or agreed to in writing, software 19 * distributed under the License is distributed on an "AS IS" BASIS, 20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 * See the License for the specific language governing permissions and 22 * limitations under the License. 23 * 24 *---------------------------------------------------------------------------- 25 * Revision Control: 26 * $Revision$ 27 * $Date$ 28 *---------------------------------------------------------------------------- 29 */ 30 31 #include "eas_types.h" 32 #include "eas_math.h" 33 34 #define MANTISSA_SHIFT 27 35 #define MANTISSA_MASK 0x0000000f 36 #define MANTISSA_LSB_SHIFT 7 37 #define MANTISSA_LSB_MASK 0x000fffff 38 #define LOG_EXPONENT_SHIFT 10 39 #define INTERPOLATION_SHIFT 20 40 #define MAX_NEGATIVE (-2147483647-1) 41 42 /* log lookup table */ 43 static const EAS_U16 eas_log2_table[] = 44 { 45 0, 90, 174, 254, 330, 402, 470, 536, 46 599, 659, 717, 773, 827, 879, 929, 977, 47 1024 48 }; 49 50 /*---------------------------------------------------------------------------- 51 * EAS_flog2() 52 *---------------------------------------------------------------------------- 53 * Purpose: 54 * Calculates the log2 of a 32-bit fixed point value 55 * 56 * Inputs: 57 * n = value of interest 58 * 59 * Outputs: 60 * returns the log2 of n 61 * 62 *---------------------------------------------------------------------------- 63 */ 64 EAS_I32 EAS_flog2 (EAS_U32 n) 65 { 66 EAS_U32 exp; 67 EAS_U32 interp; 68 69 /* check for error condition */ 70 if (n == 0) 71 return MAX_NEGATIVE; 72 73 /* find exponent */ 74 for (exp = 31; exp > 0; exp--) 75 { 76 /* shift until we get a 1 bit in bit 31 */ 77 if ((n & (EAS_U32) MAX_NEGATIVE) != 0) 78 break; 79 n <<= 1; 80 } 81 /*lint -e{701} use shift for performance */ 82 exp <<= LOG_EXPONENT_SHIFT; 83 84 /* get the least significant bits for interpolation */ 85 interp = (n >> MANTISSA_LSB_SHIFT) & MANTISSA_LSB_MASK; 86 87 /* get the most significant bits for mantissa lookup */ 88 n = (n >> MANTISSA_SHIFT) & MANTISSA_MASK; 89 90 /* interpolate mantissa */ 91 interp = ((eas_log2_table[n+1] - eas_log2_table[n]) * interp) >> INTERPOLATION_SHIFT; 92 exp += eas_log2_table[n] + interp; 93 94 return (EAS_I32) exp; 95 } 96 97