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
Generated on Tue Feb 2 09:33:31 2010 for IT++ by Doxygen 1.6.2