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   // 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
SourceForge Logo

Generated on Sun Dec 9 17:38:48 2007 for IT++ by Doxygen 1.5.4