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
Generated on Tue Nov 23 08:45:11 2010 for IT++ by Doxygen 1.6.1