IT++ Logo
fix.cpp
Go to the documentation of this file.
1 
29 #include <itpp/fixed/fix.h>
30 #include <itpp/base/itassert.h>
31 #include <cstdio>
32 #include <iostream>
33 
34 
35 namespace itpp
36 {
37 
39 {
40  shift = x.shift;
41  re = apply_o_mode(x.re);
42  return *this;
43 }
44 
45 Fix& Fix::operator=(const int x)
46 {
47  shift = 0;
48  re = apply_o_mode(x);
49  return *this;
50 }
51 
53 {
54  shift = assert_shifts(*this, x);
55  re = apply_o_mode(re + x.re);
56  return *this;
57 }
58 
59 Fix& Fix::operator+=(const int x)
60 {
61  assert_shifts(*this, x);
62  re = apply_o_mode(re + x);
63  return *this;
64 }
65 
67 {
68  shift = assert_shifts(*this, x);
69  re = apply_o_mode(re - x.re);
70  return *this;
71 }
72 
73 Fix& Fix::operator-=(const int x)
74 {
75  assert_shifts(*this, x);
76  re = apply_o_mode(re - x);
77  return *this;
78 }
79 
81 {
82  shift += x.shift;
83  re = apply_o_mode(re * x.re);
84  return *this;
85 }
86 
87 Fix& Fix::operator*=(const int x)
88 {
89  re = apply_o_mode(re * x);
90  return *this;
91 }
92 
94 {
95  shift -= x.shift;
96  re = apply_o_mode(re / x.re);
97  return *this;
98 }
99 
100 Fix& Fix::operator/=(const int x)
101 {
102  re = apply_o_mode(re / x);
103  return *this;
104 }
105 
107 {
108  return Fix(-re, shift, 0, 0);
109 }
110 
111 Fix& Fix::operator<<=(const int n)
112 {
113  it_assert_debug(n >= 0, "Fix::operator<<=: n cannot be negative!");
114  shift += n;
115  re = apply_o_mode(re << n);
116  return *this;
117 }
118 
119 Fix& Fix::operator>>=(const int n)
120 {
121  shift -= n;
123  return *this;
124 }
125 
126 void Fix::set(double x, int n)
127 {
128  shift = n;
130 }
131 
132 void Fix::set(double x, int n, q_mode q)
133 {
134  shift = n;
135  re = scale_and_apply_modes(x, q);
136 }
137 
138 void Fix::lshift(int n)
139 {
140  it_assert_debug(n >= 0, "Fix::lshift: n cannot be negative!");
141  shift += n;
142  re = apply_o_mode(re << n);
143 }
144 
145 void Fix::rshift(int n)
146 {
147  shift -= n;
149 }
150 
151 void Fix::rshift(int n, q_mode q)
152 {
153  shift -= n;
154  re = rshift_and_apply_q_mode(re, n, q);
155 }
156 
157 double Fix::unfix() const
158 {
159  it_assert_debug(shift >= -63 && shift <= 64, "Fix::unfix: Illegal shift!");
160  return double(re)*DOUBLE_POW2[64 - shift];
161 }
162 
163 void Fix::print() const
164 {
165  Fix_Base::print();
166  std::cout << "re = " << re << std::endl;
167 }
168 
169 int assert_shifts(const Fix &x, const Fix &y)
170 {
171  int ret = 0;
172 
173  if (x.shift == y.shift)
174  ret = x.shift;
175  else if (x.re == 0)
176  ret = y.shift;
177  else if (y.re == 0)
178  ret = x.shift;
179  else
180  it_error("assert_shifts: Different shifts not allowed!");
181 
182  return ret;
183 }
184 
185 int assert_shifts(const Fix &x, int y)
186 {
187  it_error_if((x.shift != 0) && (x.re != 0) && (y != 0),
188  "assert_shifts: Different shifts not allowed!");
189  return x.shift;
190 }
191 
192 std::istream &operator>>(std::istream &is, Fix &x)
193 {
194  double value;
195  is >> value;
196  if (!is.eof() && (is.peek() == '<')) {
197  int shift;
198  is.get(); // Swallow '<' sign
199  if (is.peek() == '<') {
200  is.get(); // Swallow '<' sign
201  is >> shift;
202  x.set(value, shift);
203  }
204  else {
205  is >> shift;
206  is.get(); // Swallow '>' sign
207  x.set_re(fixrep(value));
208  x.set_shift(shift);
209  }
210  }
211  else {
212  // Change data representation but keep shift
213  x.set_re(fixrep(value));
214  }
215  return is;
216 }
217 
218 std::ostream &operator<<(std::ostream &os, const Fix &x)
219 {
220  switch (x.get_output_mode()) {
221  case OUTPUT_FIX:
222  os << x.get_re();
223  break;
224  case OUTPUT_FIX_SHIFT:
225  os << x.get_re() << '<' << x.get_shift() << '>';
226  break;
227  case OUTPUT_FLOAT:
228  os << double(x);
229  break;
230  case OUTPUT_FLOAT_SHIFT:
231  os << double(x) << "<<" << x.get_shift();
232  break;
233  default:
234  it_error("operator<<: Illegal output mode!");
235  }
236  return os;
237 }
238 
239 // Specialization of template definition in vec.cpp
240 template<>
241 void fixvec::set(const char *values)
242 {
243  std::istringstream buffer(values);
244  int b = 0, c = 0;
245  int default_shift = 0, pos = 0, maxpos = 10;
246  if (datasize > 0) {
247  // Assume that all elements have the same shift
248  default_shift = data[0].get_shift();
249  }
250  alloc(maxpos);
251  while (buffer.peek() != EOF) {
252  switch (buffer.peek()) {
253  case ':': // reads format a:b:c or a:b
254  buffer.get();
255  if (!buffer.eof()) {
256  buffer >> b;
257  }
258  if (!buffer.eof() && buffer.peek() == ':') {
259  buffer.get();
260  if (!buffer.eof()) {
261  buffer >> c;
262  while (int(double(data[pos-1])) + b - c <= 0) {
263  pos++;
264  if (pos > maxpos) {
265  maxpos = maxpos * 2;
266  set_size(maxpos, true);
267  }
268  data[pos-1] = data[pos-2];
269  data[pos-1] += b;
270  }
271  }
272  }
273  else {
274  while (int(double(data[pos-1])) < b) {
275  pos++;
276  if (pos > maxpos) {
277  maxpos = maxpos * 2;
278  set_size(maxpos, true);
279  }
280  data[pos-1] = data[pos-2];
281  data[pos-1] += 1;
282  }
283  }
284  break;
285  case ',':
286  buffer.get();
287  break;
288  default:
289  pos++;
290  if (pos > maxpos) {
291  maxpos *= 2;
292  set_size(maxpos, true);
293  }
294  data[pos-1].set_shift(default_shift);
295  buffer >> data[pos-1]; // May override default_shift
296  while (buffer.peek() == ' ') { buffer.get(); }
297  break;
298  }
299  }
300  set_size(pos, true);
301 }
302 
303 // Specialization of template definition in mat.cpp
304 template<>
305 void fixmat::set(const char *values)
306 {
307  std::istringstream buffer(values);
308  int default_shift = 0, rows = 0, maxrows = 10, cols = 0, nocols = 0, maxcols = 10;
309  if (datasize > 0) {
310  // Assume that all elements have the same shift
311  default_shift = data[0].get_shift();
312  }
313  alloc(maxrows, maxcols);
314  while (buffer.peek() != EOF) {
315  rows++;
316  if (rows > maxrows) {
317  maxrows = maxrows * 2;
318  set_size(maxrows, maxcols, true);
319  }
320  cols = 0;
321  while ((buffer.peek() != ';') && (buffer.peek() != EOF)) {
322  if (buffer.peek() == ',') {
323  buffer.get();
324  }
325  else {
326  cols++;
327  if (cols > nocols) {
328  nocols = cols;
329  if (cols > maxcols) {
330  maxcols = maxcols * 2;
331  set_size(maxrows, maxcols, true);
332  }
333  }
334  this->operator()(rows-1, cols - 1).set_shift(default_shift);
335  buffer >> this->operator()(rows-1, cols - 1); // May override default_shift
336  while (buffer.peek() == ' ') { buffer.get(); }
337  }
338  }
339  if (!buffer.eof())
340  buffer.get();
341  }
342  set_size(rows, nocols, true);
343 }
344 
345 } //namespace itpp
SourceForge Logo

Generated on Sat May 25 2013 16:32:22 for IT++ by Doxygen 1.8.2