IT++ Logo
fix_base.cpp
Go to the documentation of this file.
1 
29 #include <itpp/fixed/fix_base.h>
30 #include <itpp/base/itassert.h>
31 #include <iostream>
32 
33 
34 namespace itpp
35 {
36 
37 // Definition and initialization of static data member
38 output_mode Fix_Base::outputmode = OUTPUT_FIX_SHIFT;
39 
40 void Fix_Base::set_output_mode(std::string o)
41 {
42  if (o == "OUTPUT_FIX")
43  outputmode = OUTPUT_FIX;
44  else if (o == "OUTPUT_FIX_SHIFT")
45  outputmode = OUTPUT_FIX_SHIFT;
46  else if (o == "OUTPUT_FLOAT")
47  outputmode = OUTPUT_FLOAT;
48  else if (o == "OUTPUT_FLOAT_SHIFT")
49  outputmode = OUTPUT_FLOAT_SHIFT;
50  else
51  it_error("Fix_Base::set_output_mode: Illegal output mode!");
52 }
53 
54 void Fix_Base::print() const
55 {
56  std::cout << "shift = " << shift << std::endl
57  << "wordlen = " << wordlen << std::endl
58  << "int(emode) = " << int(emode) << std::endl
59  << "int(omode) = " << int(omode) << std::endl
60  << "int(qmode) = " << int(qmode) << std::endl
61  << "stat_ptr = " << stat_ptr << std::endl
62  << "min = " << min << std::endl
63  << "max = " << max << std::endl
64  << "n_unused_bits = " << n_unused_bits << std::endl;
65 }
66 
68 {
69  switch (emode) {
70  case TC:
71  it_assert_debug(wordlen >= 1 && wordlen <= 64, "Fix_Base::calc_apply_o_modes: Illegal word length!");
72  max = fixrep(UINT64_POW2[wordlen - 1] - 1);
73  min = -max - 1;
74  break;
75  case US:
76  it_assert_debug(wordlen >= 0 && wordlen <= 63, "Fix_Base::calc_apply_o_modes: Illegal word length!");
77  min = 0;
78  max = fixrep(UINT64_POW2[wordlen] - 1);
79  break;
80  default:
81  it_error("Fix_Base::init: Illegal sign encoding mode!");
82  break;
83  }
84 
86 }
87 
89 {
90  fixrep ret = x;
91  bool overflow = false;
92 
93  if (ret < min) {
94  overflow = true;
95  switch (omode) {
96  case WRAP:
97  ret = fixrep((fixrep(ret) << n_unused_bits) >> n_unused_bits);
98  break;
99  case SAT:
100  ret = min;
101  break;
102  default:
103  it_error("Fix_Base::apply_o_mode: Illegal overflow mode!");
104  break;
105  }
106  }
107  else if (ret > max) {
108  overflow = true;
109  switch (omode) {
110  case WRAP:
111  ret = fixrep((fixrep(ret) << n_unused_bits) >> n_unused_bits);
112  break;
113  case SAT:
114  ret = max;
115  break;
116  default:
117  it_error("Fix_Base::apply_o_mode: Illegal overflow mode!");
118  break;
119  }
120  }
121 
122  if (stat_ptr != 0)
123  stat_ptr->sample(double(ret), overflow);
124 
125  return ret;
126 }
127 
129 {
130  it_assert_debug(shift >= -64 && shift <= 63, "Fix_Base::scale_and_apply_modes: Illegal shift!");
131  fixrep ret = 0;
132  double scaled_value = x * DOUBLE_POW2[shift + 64];
133 
134  switch (q) {
135  case RND:
136  ret = apply_o_mode(fixrep(std::floor(scaled_value + 0.5)));
137  break;
138  case RND_ZERO:
139  if (x < 0)
140  ret = apply_o_mode(fixrep(std::floor(scaled_value + 0.5)));
141  else
142  ret = apply_o_mode(fixrep(-std::floor(-scaled_value + 0.5)));
143  break;
144  case RND_MIN_INF:
145  ret = apply_o_mode(fixrep(-std::floor(-scaled_value + 0.5)));
146  break;
147  case RND_INF:
148  if (x < 0)
149  ret = apply_o_mode(fixrep(scaled_value - 0.5));
150  else
151  ret = apply_o_mode(fixrep(scaled_value + 0.5));
152  break;
153  case RND_CONV:
154  if (scaled_value == std::floor(scaled_value) + 0.5)
155  ret = apply_o_mode((fixrep(round(scaled_value)) >> 1) << 1);
156  else
157  ret = apply_o_mode(fixrep(std::floor(scaled_value + 0.5)));
158  break;
159  case RND_CONV_ODD:
160  if (scaled_value == std::floor(scaled_value) + 0.5)
161  if (scaled_value < 0)
162  ret = apply_o_mode(((fixrep(std::ceil(scaled_value)) >> 1) << 1) - 1);
163  else
164  ret = apply_o_mode(((fixrep(std::floor(scaled_value)) >> 1) << 1) + 1);
165  else
166  ret = apply_o_mode(fixrep(std::floor(scaled_value + 0.5)));
167  break;
168  case TRN:
169  ret = apply_o_mode(fixrep(std::floor(scaled_value)));
170  break;
171  case TRN_ZERO:
172  ret = apply_o_mode(fixrep(scaled_value));
173  break;
174  default:
175  it_error("Fix_Base::scale_and_apply_modes: Illegal quantization mode!");
176  break;
177  }
178 
179  return ret;
180 }
181 
183 {
184  it_assert_debug(n >= 0, "Fix_Base::rshift_and_apply_q_mode: n cannot be negative!");
185  fixrep ret = 0;
186 
187  if (n == 0) {
188  ret = x;
189  }
190  else {
191  switch (q) {
192  case RND:
193  // Add the most significant deleted bit to the remaining bits
194  ret = ((x >> (n - 1)) + 1) >> 1;
195  break;
196  case RND_ZERO:
197  // If the most significant deleted bit is 1,
198  // and either the sign bit or at least one other deleted bit is 1,
199  // add 1 to the remaining bits
200  if ((x & (fixrep(1) << (n - 1))) && ((x < 0) || (x & ((fixrep(1) << (n - 1)) - 1))))
201  ret = (x >> n) + 1;
202  else
203  ret = x >> n;
204  break;
205  case RND_MIN_INF:
206  // If the most significant deleted bit is 1,
207  // and at least one other deleted bit is 1,
208  // add 1 to the remaining bits
209  if ((x & (fixrep(1) << (n - 1))) && (x & ((fixrep(1) << (n - 1)) - 1)))
210  ret = (x >> n) + 1;
211  else
212  ret = x >> n;
213  break;
214  case RND_INF:
215  // If the most significant deleted bit is 1,
216  // and either the inverted value of the sign bit or at least one other deleted bit is 1,
217  // add 1 to the remaining bits
218  if ((x & (fixrep(1) << (n - 1))) && ((x >= 0) || (x & ((fixrep(1) << (n - 1)) - 1))))
219  ret = (x >> n) + 1;
220  else
221  ret = x >> n;
222  break;
223  case RND_CONV:
224  // If the most significant deleted bit is 1,
225  // and either the least significant of the remaining bits or at least one other deleted bit is 1,
226  // add 1 to the remaining bits
227  if ((x & (fixrep(1) << (n - 1))) && ((x & (fixrep(1) << n)) || (x & ((fixrep(1) << (n - 1)) - 1))))
228  ret = (x >> n) + 1;
229  else
230  ret = x >> n;
231  break;
232  case RND_CONV_ODD:
233  // If the most significant deleted bit is 1,
234  // and either the least significant of the remaining bits is 0 or at least one other deleted bit is 1,
235  // add 1 to the remaining bits
236  if ((x & (fixrep(1) << (n - 1))) && (!(x & (fixrep(1) << n)) || (x & ((fixrep(1) << (n - 1)) - 1))))
237  ret = (x >> n) + 1;
238  else
239  ret = x >> n;
240  break;
241  case TRN:
242  // Just copy the remaining bits
243  ret = x >> n;
244  break;
245  case TRN_ZERO:
246  // If the sign bit is 1,
247  // and either the most significant deleted bit or at least one other deleted bit is 1,
248  // add 1 to the remaining bits
249  if ((x < 0) && (x & ((fixrep(1) << n) - 1)))
250  ret = (x >> n) + 1;
251  else
252  ret = x >> n;
253  break;
254  default:
255  it_error("Fix_Base::rshift_and_apply_q_mode: Illegal quantization mode!");
256  break;
257  }
258  }
259 
260  if (stat_ptr != 0)
261  stat_ptr->sample(double(ret), false);
262 
263  return ret;
264 }
265 
266 } // namespace itpp
SourceForge Logo

Generated on Sat Jul 6 2013 10:54:24 for IT++ by Doxygen 1.8.2