IT++ Logo Newcom Logo

fix_base.cpp

Go to the documentation of this file.
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
SourceForge Logo

Generated on Sat Aug 25 23:40:27 2007 for IT++ by Doxygen 1.5.2