IT++ Logo Newcom Logo

fix.cpp

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

Generated on Thu Apr 19 14:20:37 2007 for IT++ by Doxygen 1.4.6