IT++ Logo

fix_base.cpp

Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Tue Nov 23 08:45:11 2010 for IT++ by Doxygen 1.6.1