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
Generated on Thu Apr 19 14:20:37 2007 for IT++ by Doxygen 1.4.6