IT++ Logo
fix_base.cpp
Go to the documentation of this file.
00001 
00029 #include <itpp/fixed/fix_base.h>
00030 #include <itpp/base/itassert.h>
00031 #include <iostream>
00032 
00033 
00034 namespace itpp
00035 {
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Wed Jul 27 2011 16:27:05 for IT++ by Doxygen 1.7.4