00001 00030 #include <itpp/fixed/fix_base.h> 00031 #include <itpp/base/itassert.h> 00032 #include <iostream> 00033 00034 00035 namespace itpp { 00036 00037 // Definition and initialization of static data member 00038 output_mode Fix_Base::outputmode = OUTPUT_FIX_SHIFT; 00039 00040 void Fix_Base::set_output_mode(std::string o) 00041 { 00042 if (o == "OUTPUT_FIX") 00043 outputmode = OUTPUT_FIX; 00044 else if (o == "OUTPUT_FIX_SHIFT") 00045 outputmode = OUTPUT_FIX_SHIFT; 00046 else if (o == "OUTPUT_FLOAT") 00047 outputmode = OUTPUT_FLOAT; 00048 else if (o == "OUTPUT_FLOAT_SHIFT") 00049 outputmode = OUTPUT_FLOAT_SHIFT; 00050 else 00051 it_error("Fix_Base::set_output_mode: Illegal output mode!"); 00052 } 00053 00054 void Fix_Base::print() const 00055 { 00056 std::cout << "shift = " << shift << std::endl 00057 << "wordlen = " << wordlen << std::endl 00058 << "int(emode) = " << int(emode) << std::endl 00059 << "int(omode) = " << int(omode) << std::endl 00060 << "int(qmode) = " << int(qmode) << std::endl 00061 << "stat_ptr = " << stat_ptr << std::endl 00062 << "min = " << min << std::endl 00063 << "max = " << max << std::endl 00064 << "n_unused_bits = " << n_unused_bits << std::endl; 00065 } 00066 00067 void Fix_Base::init() 00068 { 00069 switch (emode) { 00070 case TC: 00071 it_assert_debug(wordlen >= 1 && wordlen <= 64, "Fix_Base::calc_apply_o_modes: Illegal word length!"); 00072 max = fixrep(UINT64_POW2[wordlen - 1] - 1); 00073 min = -max - 1; 00074 break; 00075 case US: 00076 it_assert_debug(wordlen >= 0 && wordlen <= 63, "Fix_Base::calc_apply_o_modes: Illegal word length!"); 00077 min = 0; 00078 max = fixrep(UINT64_POW2[wordlen] - 1); 00079 break; 00080 default: 00081 it_error("Fix_Base::init: Illegal sign encoding mode!"); 00082 break; 00083 } 00084 00085 n_unused_bits = MAX_WORDLEN - wordlen; 00086 } 00087 00088 fixrep Fix_Base::apply_o_mode(fixrep x) const 00089 { 00090 fixrep ret = x; 00091 bool overflow = false; 00092 00093 if (ret < min) { 00094 overflow = true; 00095 switch (omode) { 00096 case WRAP: 00097 ret = fixrep((fixrep(ret) << n_unused_bits) >> n_unused_bits); 00098 break; 00099 case SAT: 00100 ret = min; 00101 break; 00102 default: 00103 it_error("Fix_Base::apply_o_mode: Illegal overflow mode!"); 00104 break; 00105 } 00106 } 00107 else if (ret > max) { 00108 overflow = true; 00109 switch (omode) { 00110 case WRAP: 00111 ret = fixrep((fixrep(ret) << n_unused_bits) >> n_unused_bits); 00112 break; 00113 case SAT: 00114 ret = max; 00115 break; 00116 default: 00117 it_error("Fix_Base::apply_o_mode: Illegal overflow mode!"); 00118 break; 00119 } 00120 } 00121 00122 if (stat_ptr != 0) 00123 stat_ptr->sample(double(ret), overflow); 00124 00125 return ret; 00126 } 00127 00128 fixrep Fix_Base::scale_and_apply_modes(double x, q_mode q) const 00129 { 00130 it_assert_debug(shift>=-64 && shift<=63, "Fix_Base::scale_and_apply_modes: Illegal shift!"); 00131 fixrep ret = 0; 00132 double scaled_value = x*DOUBLE_POW2[shift + 64]; 00133 00134 switch (q) { 00135 case RND: 00136 ret = apply_o_mode(fixrep(std::floor(scaled_value + 0.5))); 00137 break; 00138 case RND_ZERO: 00139 if (x < 0) 00140 ret = apply_o_mode(fixrep(std::floor(scaled_value + 0.5))); 00141 else 00142 ret = apply_o_mode(fixrep(-std::floor(-scaled_value + 0.5))); 00143 break; 00144 case RND_MIN_INF: 00145 ret = apply_o_mode(fixrep(-std::floor(-scaled_value + 0.5))); 00146 break; 00147 case RND_INF: 00148 if (x < 0) 00149 ret = apply_o_mode(fixrep(scaled_value - 0.5)); 00150 else 00151 ret = apply_o_mode(fixrep(scaled_value + 0.5)); 00152 break; 00153 case RND_CONV: 00154 if (scaled_value == std::floor(scaled_value) + 0.5) 00155 ret = apply_o_mode((fixrep(round(scaled_value)) >> 1) << 1); 00156 else 00157 ret = apply_o_mode(fixrep(std::floor(scaled_value + 0.5))); 00158 break; 00159 case RND_CONV_ODD: 00160 if (scaled_value == std::floor(scaled_value) + 0.5) 00161 if (scaled_value < 0) 00162 ret = apply_o_mode(((fixrep(std::ceil(scaled_value)) >> 1) << 1) - 1); 00163 else 00164 ret = apply_o_mode(((fixrep(std::floor(scaled_value)) >> 1) << 1) + 1); 00165 else 00166 ret = apply_o_mode(fixrep(std::floor(scaled_value + 0.5))); 00167 break; 00168 case TRN: 00169 ret = apply_o_mode(fixrep(std::floor(scaled_value))); 00170 break; 00171 case TRN_ZERO: 00172 ret = apply_o_mode(fixrep(scaled_value)); 00173 break; 00174 default: 00175 it_error("Fix_Base::scale_and_apply_modes: Illegal quantization mode!"); 00176 break; 00177 } 00178 00179 return ret; 00180 } 00181 00182 fixrep Fix_Base::rshift_and_apply_q_mode(fixrep x, int n, q_mode q) const 00183 { 00184 it_assert_debug(n >= 0, "Fix_Base::rshift_and_apply_q_mode: n cannot be negative!"); 00185 fixrep ret = 0; 00186 00187 if (n == 0) { 00188 ret = x; 00189 } 00190 else { 00191 switch (q) { 00192 case RND: 00193 // Add the most significant deleted bit to the remaining bits 00194 ret = ((x >> (n - 1)) + 1) >> 1; 00195 break; 00196 case RND_ZERO: 00197 // If the most significant deleted bit is 1, 00198 // and either the sign bit or at least one other deleted bit is 1, 00199 // add 1 to the remaining bits 00200 if ((x & (fixrep(1) << (n - 1))) && ((x < 0) || (x & ((fixrep(1) << (n - 1)) - 1)))) 00201 ret = (x >> n) + 1; 00202 else 00203 ret = x >> n; 00204 break; 00205 case RND_MIN_INF: 00206 // If the most significant deleted bit is 1, 00207 // and at least one other deleted bit is 1, 00208 // add 1 to the remaining bits 00209 if ((x & (fixrep(1) << (n - 1))) && (x & ((fixrep(1) << (n - 1)) - 1))) 00210 ret = (x >> n) + 1; 00211 else 00212 ret = x >> n; 00213 break; 00214 case RND_INF: 00215 // If the most significant deleted bit is 1, 00216 // and either the inverted value of the sign bit or at least one other deleted bit is 1, 00217 // add 1 to the remaining bits 00218 if ((x & (fixrep(1) << (n - 1))) && ((x >= 0) || (x & ((fixrep(1) << (n - 1)) - 1)))) 00219 ret = (x >> n) + 1; 00220 else 00221 ret = x >> n; 00222 break; 00223 case RND_CONV: 00224 // If the most significant deleted bit is 1, 00225 // and either the least significant of the remaining bits or at least one other deleted bit is 1, 00226 // add 1 to the remaining bits 00227 if ((x & (fixrep(1) << (n - 1))) && ((x & (fixrep(1) << n)) || (x & ((fixrep(1) << (n - 1)) - 1)))) 00228 ret = (x >> n) + 1; 00229 else 00230 ret = x >> n; 00231 break; 00232 case RND_CONV_ODD: 00233 // If the most significant deleted bit is 1, 00234 // and either the least significant of the remaining bits is 0 or at least one other deleted bit is 1, 00235 // add 1 to the remaining bits 00236 if ((x & (fixrep(1) << (n - 1))) && (!(x & (fixrep(1) << n)) || (x & ((fixrep(1) << (n - 1)) - 1)))) 00237 ret = (x >> n) + 1; 00238 else 00239 ret = x >> n; 00240 break; 00241 case TRN: 00242 // Just copy the remaining bits 00243 ret = x >> n; 00244 break; 00245 case TRN_ZERO: 00246 // If the sign bit is 1, 00247 // and either the most significant deleted bit or at least one other deleted bit is 1, 00248 // add 1 to the remaining bits 00249 if ((x < 0) && (x & ((fixrep(1) << n) - 1))) 00250 ret = (x >> n) + 1; 00251 else 00252 ret = x >> n; 00253 break; 00254 default: 00255 it_error("Fix_Base::rshift_and_apply_q_mode: Illegal quantization mode!"); 00256 break; 00257 } 00258 } 00259 00260 if (stat_ptr != 0) 00261 stat_ptr->sample(double(ret), false); 00262 00263 return ret; 00264 } 00265 00266 } // namespace itpp
Generated on Sat Apr 19 10:42:05 2008 for IT++ by Doxygen 1.5.5