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