IT++ Logo

fix.cpp

Go to the documentation of this file.
00001 
00030 #include <itpp/fixed/fix.h>
00031 #include <itpp/base/itassert.h>
00032 #include <cstdio>
00033 #include <iostream>
00034 
00035 
00036 namespace itpp
00037 {
00038 
00039 Fix& Fix::operator=(const Fix &x)
00040 {
00041   shift = x.shift;
00042   re = apply_o_mode(x.re);
00043   return *this;
00044 }
00045 
00046 Fix& Fix::operator=(const int x)
00047 {
00048   shift = 0;
00049   re = apply_o_mode(x);
00050   return *this;
00051 }
00052 
00053 Fix& Fix::operator+=(const Fix &x)
00054 {
00055   shift = assert_shifts(*this, x);
00056   re = apply_o_mode(re + x.re);
00057   return *this;
00058 }
00059 
00060 Fix& Fix::operator+=(const int x)
00061 {
00062   assert_shifts(*this, x);
00063   re = apply_o_mode(re + x);
00064   return *this;
00065 }
00066 
00067 Fix& Fix::operator-=(const Fix &x)
00068 {
00069   shift = assert_shifts(*this, x);
00070   re = apply_o_mode(re - x.re);
00071   return *this;
00072 }
00073 
00074 Fix& Fix::operator-=(const int x)
00075 {
00076   assert_shifts(*this, x);
00077   re = apply_o_mode(re - x);
00078   return *this;
00079 }
00080 
00081 Fix& Fix::operator*=(const Fix &x)
00082 {
00083   shift += x.shift;
00084   re = apply_o_mode(re * x.re);
00085   return *this;
00086 }
00087 
00088 Fix& Fix::operator*=(const int x)
00089 {
00090   re = apply_o_mode(re * x);
00091   return *this;
00092 }
00093 
00094 Fix& Fix::operator/=(const Fix &x)
00095 {
00096   shift -= x.shift;
00097   re = apply_o_mode(re / x.re);
00098   return *this;
00099 }
00100 
00101 Fix& Fix::operator/=(const int x)
00102 {
00103   re = apply_o_mode(re / x);
00104   return *this;
00105 }
00106 
00107 Fix Fix::operator-() const
00108 {
00109   return Fix(-re, shift, 0, 0);
00110 }
00111 
00112 Fix& Fix::operator<<=(const int n)
00113 {
00114   it_assert_debug(n >= 0, "Fix::operator<<=: n cannot be negative!");
00115   shift += n;
00116   re = apply_o_mode(re << n);
00117   return *this;
00118 }
00119 
00120 Fix& Fix::operator>>=(const int n)
00121 {
00122   shift -= n;
00123   re = rshift_and_apply_q_mode(re, n);
00124   return *this;
00125 }
00126 
00127 void Fix::set(double x, int n)
00128 {
00129   shift = n;
00130   re = scale_and_apply_modes(x);
00131 }
00132 
00133 void Fix::set(double x, int n, q_mode q)
00134 {
00135   shift = n;
00136   re = scale_and_apply_modes(x, q);
00137 }
00138 
00139 void Fix::lshift(int n)
00140 {
00141   it_assert_debug(n >= 0, "Fix::lshift: n cannot be negative!");
00142   shift += n;
00143   re = apply_o_mode(re << n);
00144 }
00145 
00146 void Fix::rshift(int n)
00147 {
00148   shift -= n;
00149   re = rshift_and_apply_q_mode(re, n);
00150 }
00151 
00152 void Fix::rshift(int n, q_mode q)
00153 {
00154   shift -= n;
00155   re = rshift_and_apply_q_mode(re, n, q);
00156 }
00157 
00158 double Fix::unfix() const
00159 {
00160   it_assert_debug(shift >= -63 && shift <= 64, "Fix::unfix: Illegal shift!");
00161   return double(re)*DOUBLE_POW2[64 - shift];
00162 }
00163 
00164 void Fix::print() const
00165 {
00166   Fix_Base::print();
00167   std::cout << "re = " << re << std::endl;
00168 }
00169 
00170 int assert_shifts(const Fix &x, const Fix &y)
00171 {
00172   int ret = 0;
00173 
00174   if (x.shift == y.shift)
00175     ret = x.shift;
00176   else if (x.re == 0)
00177     ret = y.shift;
00178   else if (y.re == 0)
00179     ret = x.shift;
00180   else
00181     it_error("assert_shifts: Different shifts not allowed!");
00182 
00183   return ret;
00184 }
00185 
00186 int assert_shifts(const Fix &x, int y)
00187 {
00188   it_error_if((x.shift != 0) && (x.re != 0) && (y != 0),
00189               "assert_shifts: Different shifts not allowed!");
00190   return x.shift;
00191 }
00192 
00193 std::istream &operator>>(std::istream &is, Fix &x)
00194 {
00195   double value;
00196   is >> value;
00197   if (!is.eof() && (is.peek() == '<')) {
00198     int shift;
00199     is.get();  // Swallow '<' sign
00200     if (is.peek() == '<') {
00201       is.get();  // Swallow '<' sign
00202       is >> shift;
00203       x.set(value, shift);
00204     }
00205     else {
00206       is >> shift;
00207       is.get();  // Swallow '>' sign
00208       x.set_re(fixrep(value));
00209       x.set_shift(shift);
00210     }
00211   }
00212   else {
00213     // Change data representation but keep shift
00214     x.set_re(fixrep(value));
00215   }
00216   return is;
00217 }
00218 
00219 std::ostream &operator<<(std::ostream &os, const Fix &x)
00220 {
00221   switch (x.get_output_mode()) {
00222   case OUTPUT_FIX:
00223     os << x.get_re();
00224     break;
00225   case OUTPUT_FIX_SHIFT:
00226     os << x.get_re() << '<' << x.get_shift() << '>';
00227     break;
00228   case OUTPUT_FLOAT:
00229     os << double(x);
00230     break;
00231   case OUTPUT_FLOAT_SHIFT:
00232     os << double(x) << "<<" << x.get_shift();
00233     break;
00234   default:
00235     it_error("operator<<: Illegal output mode!");
00236   }
00237   return os;
00238 }
00239 
00240 // Specialization of template definition in vec.cpp
00241 template<>
00242 void fixvec::set(const char *values)
00243 {
00244   std::istringstream buffer(values);
00245   int b = 0, c = 0;
00246   int default_shift = 0, pos = 0, maxpos = 10;
00247   if (datasize > 0) {
00248     // Assume that all elements have the same shift
00249     default_shift = data[0].get_shift();
00250   }
00251   alloc(maxpos);
00252   while (buffer.peek() != EOF) {
00253     switch (buffer.peek()) {
00254     case ':': // reads format a:b:c or a:b
00255       buffer.get();
00256       if (!buffer.eof()) {
00257         buffer >> b;
00258       }
00259       if (!buffer.eof() && buffer.peek() == ':') {
00260         buffer.get();
00261         if (!buffer.eof()) {
00262           buffer >> c;
00263           while (int(double(data[pos-1])) + b - c <= 0) {
00264             pos++;
00265             if (pos > maxpos) {
00266               maxpos = maxpos * 2;
00267               set_size(maxpos, true);
00268             }
00269             data[pos-1] = data[pos-2];
00270             data[pos-1] += b;
00271           }
00272         }
00273       }
00274       else {
00275         while (int(double(data[pos-1])) < b) {
00276           pos++;
00277           if (pos > maxpos) {
00278             maxpos = maxpos * 2;
00279             set_size(maxpos, true);
00280           }
00281           data[pos-1] = data[pos-2];
00282           data[pos-1] += 1;
00283         }
00284       }
00285       break;
00286     case ',':
00287       buffer.get();
00288       break;
00289     default:
00290       pos++;
00291       if (pos > maxpos) {
00292         maxpos *= 2;
00293         set_size(maxpos, true);
00294       }
00295       data[pos-1].set_shift(default_shift);
00296       buffer >> data[pos-1];  // May override default_shift
00297       while (buffer.peek() == ' ') { buffer.get(); }
00298       break;
00299     }
00300   }
00301   set_size(pos, true);
00302 }
00303 
00304 // Specialization of template definition in mat.cpp
00305 template<>
00306 void fixmat::set(const char *values)
00307 {
00308   std::istringstream buffer(values);
00309   int default_shift = 0, rows = 0, maxrows = 10, cols = 0, nocols = 0, maxcols = 10;
00310   if (datasize > 0) {
00311     // Assume that all elements have the same shift
00312     default_shift = data[0].get_shift();
00313   }
00314   alloc(maxrows, maxcols);
00315   while (buffer.peek() != EOF) {
00316     rows++;
00317     if (rows > maxrows) {
00318       maxrows = maxrows * 2;
00319       set_size(maxrows, maxcols, true);
00320     }
00321     cols = 0;
00322     while ((buffer.peek() != ';') && (buffer.peek() != EOF)) {
00323       if (buffer.peek() == ',') {
00324         buffer.get();
00325       }
00326       else {
00327         cols++;
00328         if (cols > nocols) {
00329           nocols = cols;
00330           if (cols > maxcols) {
00331             maxcols = maxcols * 2;
00332             set_size(maxrows, maxcols, true);
00333           }
00334         }
00335         this->operator()(rows-1, cols - 1).set_shift(default_shift);
00336         buffer >> this->operator()(rows-1, cols - 1);  // May override default_shift
00337         while (buffer.peek() == ' ') { buffer.get(); }
00338       }
00339     }
00340     if (!buffer.eof())
00341       buffer.get();
00342   }
00343   set_size(rows, nocols, true);
00344 }
00345 
00346 } //namespace itpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Wed Jan 20 23:03:05 2010 for IT++ by Doxygen 1.6.2