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

Generated on Sat Apr 19 10:42:05 2008 for IT++ by Doxygen 1.5.5