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 #include <cstdio>
00034 
00035 namespace itpp
00036 {
00037 
00038 Fix& Fix::operator=(const Fix &x)
00039 {
00040   shift = x.shift;
00041   re = apply_o_mode(x.re);
00042   return *this;
00043 }
00044 
00045 Fix& Fix::operator=(const int x)
00046 {
00047   shift = 0;
00048   re = apply_o_mode(x);
00049   return *this;
00050 }
00051 
00052 Fix& Fix::operator+=(const Fix &x)
00053 {
00054   shift = assert_shifts(*this, x);
00055   re = apply_o_mode(re + x.re);
00056   return *this;
00057 }
00058 
00059 Fix& Fix::operator+=(const int x)
00060 {
00061   assert_shifts(*this, x);
00062   re = apply_o_mode(re + x);
00063   return *this;
00064 }
00065 
00066 Fix& Fix::operator-=(const Fix &x)
00067 {
00068   shift = assert_shifts(*this, x);
00069   re = apply_o_mode(re - x.re);
00070   return *this;
00071 }
00072 
00073 Fix& Fix::operator-=(const int x)
00074 {
00075   assert_shifts(*this, x);
00076   re = apply_o_mode(re - x);
00077   return *this;
00078 }
00079 
00080 Fix& Fix::operator*=(const Fix &x)
00081 {
00082   shift += x.shift;
00083   re = apply_o_mode(re * x.re);
00084   return *this;
00085 }
00086 
00087 Fix& Fix::operator*=(const int x)
00088 {
00089   re = apply_o_mode(re * x);
00090   return *this;
00091 }
00092 
00093 Fix& Fix::operator/=(const Fix &x)
00094 {
00095   shift -= x.shift;
00096   re = apply_o_mode(re / x.re);
00097   return *this;
00098 }
00099 
00100 Fix& Fix::operator/=(const int x)
00101 {
00102   re = apply_o_mode(re / x);
00103   return *this;
00104 }
00105 
00106 Fix Fix::operator-() const
00107 {
00108   return Fix(-re, shift, 0, 0);
00109 }
00110 
00111 Fix& Fix::operator<<=(const int n)
00112 {
00113   it_assert_debug(n >= 0, "Fix::operator<<=: n cannot be negative!");
00114   shift += n;
00115   re = apply_o_mode(re << n);
00116   return *this;
00117 }
00118 
00119 Fix& Fix::operator>>=(const int n)
00120 {
00121   shift -= n;
00122   re = rshift_and_apply_q_mode(re, n);
00123   return *this;
00124 }
00125 
00126 void Fix::set(double x, int n)
00127 {
00128   shift = n;
00129   re = scale_and_apply_modes(x);
00130 }
00131 
00132 void Fix::set(double x, int n, q_mode q)
00133 {
00134   shift = n;
00135   re = scale_and_apply_modes(x, q);
00136 }
00137 
00138 void Fix::lshift(int n)
00139 {
00140   it_assert_debug(n >= 0, "Fix::lshift: n cannot be negative!");
00141   shift += n;
00142   re = apply_o_mode(re << n);
00143 }
00144 
00145 void Fix::rshift(int n)
00146 {
00147   shift -= n;
00148   re = rshift_and_apply_q_mode(re, n);
00149 }
00150 
00151 void Fix::rshift(int n, q_mode q)
00152 {
00153   shift -= n;
00154   re = rshift_and_apply_q_mode(re, n, q);
00155 }
00156 
00157 double Fix::unfix() const
00158 {
00159   it_assert_debug(shift >= -63 && shift <= 64, "Fix::unfix: Illegal shift!");
00160   return double(re)*DOUBLE_POW2[64 - shift];
00161 }
00162 
00163 void Fix::print() const
00164 {
00165   Fix_Base::print();
00166   std::cout << "re = " << re << std::endl;
00167 }
00168 
00169 int assert_shifts(const Fix &x, const Fix &y)
00170 {
00171   int ret = 0;
00172 
00173   if (x.shift == y.shift)
00174     ret = x.shift;
00175   else if (x.re == 0)
00176     ret = y.shift;
00177   else if (y.re == 0)
00178     ret = x.shift;
00179   else
00180     it_error("assert_shifts: Different shifts not allowed!");
00181 
00182   return ret;
00183 }
00184 
00185 int assert_shifts(const Fix &x, int y)
00186 {
00187   it_error_if((x.shift != 0) && (x.re != 0) && (y != 0),
00188               "assert_shifts: Different shifts not allowed!");
00189   return x.shift;
00190 }
00191 
00192 std::istream &operator>>(std::istream &is, Fix &x)
00193 {
00194   double value;
00195   is >> value;
00196   if (!is.eof() && (is.peek() == '<')) {
00197     int shift;
00198     is.get();  // Swallow '<' sign
00199     if (is.peek() == '<') {
00200       is.get();  // Swallow '<' sign
00201       is >> shift;
00202       x.set(value, shift);
00203     }
00204     else {
00205       is >> shift;
00206       is.get();  // Swallow '>' sign
00207       x.set_re(fixrep(value));
00208       x.set_shift(shift);
00209     }
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 void fixvec::set(const char *values)
00242 {
00243   std::istringstream buffer(values);
00244   int b = 0, c = 0;
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       }
00273       else {
00274         while (int(double(data[pos-1])) < b) {
00275           pos++;
00276           if (pos > maxpos) {
00277             maxpos = maxpos * 2;
00278             set_size(maxpos, true);
00279           }
00280           data[pos-1] = data[pos-2];
00281           data[pos-1] += 1;
00282         }
00283       }
00284       break;
00285     case ',':
00286       buffer.get();
00287       break;
00288     default:
00289       pos++;
00290       if (pos > maxpos) {
00291         maxpos *= 2;
00292         set_size(maxpos, true);
00293       }
00294       data[pos-1].set_shift(default_shift);
00295       buffer >> data[pos-1];  // May override default_shift
00296       while (buffer.peek() == ' ') { buffer.get(); }
00297       break;
00298     }
00299   }
00300   set_size(pos, true);
00301 }
00302 
00303 // Specialization of template definition in mat.cpp
00304 template<>
00305 void 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       }
00325       else {
00326         cols++;
00327         if (cols > nocols) {
00328           nocols = cols;
00329           if (cols > maxcols) {
00330             maxcols = maxcols * 2;
00331             set_size(maxrows, maxcols, true);
00332           }
00333         }
00334         this->operator()(rows-1, cols - 1).set_shift(default_shift);
00335         buffer >> this->operator()(rows-1, cols - 1);  // May override default_shift
00336         while (buffer.peek() == ' ') { buffer.get(); }
00337       }
00338     }
00339     if (!buffer.eof())
00340       buffer.get();
00341   }
00342   set_size(rows, nocols, true);
00343 }
00344 
00345 } //namespace itpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Wed Mar 2 2011 22:05:15 for IT++ by Doxygen 1.7.3