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