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
Generated on Sun Dec 9 17:38:48 2007 for IT++ by Doxygen 1.5.4