1 /*---------------------------------------------------------------------------* 2 * sh_down.h * 3 * * 4 * Copyright 2007, 2008 Nuance Communciations, Inc. * 5 * * 6 * Licensed under the Apache License, Version 2.0 (the 'License'); * 7 * you may not use this file except in compliance with the License. * 8 * * 9 * You may obtain a copy of the License at * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, software * 13 * distributed under the License is distributed on an 'AS IS' BASIS, * 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 * See the License for the specific language governing permissions and * 16 * limitations under the License. * 17 * * 18 *---------------------------------------------------------------------------*/ 19 20 #ifndef _SH_DOWN_INL_ 21 #define _SH_DOWN_INL_ 22 23 #include <limits.h> 24 25 #include "fronttyp.h" 26 #include "setting.h" 27 #include "portable.h" 28 29 #define SHIFT_DOWN(X,S) ((S) > 0 ? shift_down_inline ((X), (S)) : (X)) 30 #define SHIFT_UP(X,S) ((S) > 0 ? shift_up_inline ((X), (S)) : (X)) 31 32 #define COND_SHIFT_DOWN(X,S) (SHIFT_DOWN(X,S)) 33 #define COND_SHIFT_UP(X,S) (SHIFT_UP(X,S)) 34 35 static PINLINE int fixed_point_convert(float xx, int shift); 36 static PINLINE int shift_up_inline(int value, unsigned int shift); 37 static PINLINE int shift_down_inline(int value, unsigned int shift); 38 static PINLINE int fixed_round(float value); 39 40 #define TRUNCATE_ON_SHIFT 1 41 42 static PINLINE int shift_up_inline(int value, unsigned int shift) 43 { 44 /* Shift up using bit operations with max limit */ 45 int temp, retval; 46 47 ASSERT(shift > 0); 48 if (value > 0) 49 temp = value; 50 else 51 temp = -value; 52 53 retval = temp << shift; 54 55 if ((retval > (int)LONG_MAX) || (retval < temp)) /* TODO: max_val if LONG_MAX, overflow won't be detected */ 56 retval = (int)LONG_MAX; 57 if (value > 0) 58 return retval; 59 else 60 return (-retval); 61 } 62 63 64 static PINLINE int shift_down_inline(int value, unsigned int shift) 65 /* Shift down using bit operations with rounding */ 66 { 67 if (shift-- == 0) 68 return (value); 69 if (value >= 0) 70 return (((value >> shift) + 1) >> 1); 71 else 72 return (-((((-value) >> shift) + 1) >> 1)); 73 } 74 75 static PINLINE int fixed_point_convert(float xx, int shift) 76 { 77 float scaled_val; 78 79 ASSERT(shift >= 0); 80 scaled_val = xx * (0x01 << shift); 81 if (scaled_val >= 0) 82 if (scaled_val > LONG_MAX) 83 return (LONG_MAX); 84 else 85 return ((int)(scaled_val + 0.5)); 86 else 87 if (scaled_val < -LONG_MAX) 88 return (-LONG_MAX); 89 else 90 return ((int)(scaled_val - 0.5)); 91 } 92 93 static PINLINE int fixed_round(float value) 94 { 95 if (value > 0) 96 return ((int)(value + 0.5)); 97 else 98 return ((int)(value - 0.5)); 99 } 100 101 #endif 102