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
34namespace itpp
35{
36
37// Definition and initialization of static data member
38output_mode Fix_Base::outputmode = OUTPUT_FIX_SHIFT;
39
40void 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
54void 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;
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
virtual void print() const
Print restrictions.
Definition: fix_base.cpp:54
static void set_output_mode(output_mode o)
Set output mode to OUTPUT_FIX, OUTPUT_FIX_SHIFT, OUTPUT_FLOAT or OUTPUT_FLOAT_SHIFT....
Definition: fix_base.h:996
fixrep apply_o_mode(fixrep x) const
Handle overflows using overflow mode omode and make call to statistics object (if any)
Definition: fix_base.cpp:88
fixrep scale_and_apply_modes(double x) const
Convert from double to fixrep using shift and quantization mode qmode, then call limit()
Definition: fix_base.h:1044
int n_unused_bits
Number of unused (MSB) bits (help variable to speed up calculations)
Definition: fix_base.h:1037
fixrep rshift_and_apply_q_mode(fixrep x, int n) const
Right shift n bits using quantization mode qmode and make call to statistics object (if any)
Definition: fix_base.h:1048
int wordlen
Word length.
Definition: fix_base.h:1023
fixrep min
Minimum allowed value (help variable to speed up calculations)
Definition: fix_base.h:1033
void init()
Calculate help variables min, max and n_unused_bits.
Definition: fix_base.cpp:67
e_mode emode
Sign encoding mode.
Definition: fix_base.h:1025
Stat * stat_ptr
Pointer to statistics object.
Definition: fix_base.h:1031
fixrep max
Maximum allowed value (help variable to speed up calculations)
Definition: fix_base.h:1035
int shift
Accumulated bitshift (positive means left-shifted, negative means right-shifted)
Definition: fix_base.h:1021
q_mode qmode
Quantization mode.
Definition: fix_base.h:1029
o_mode omode
Overflow mode.
Definition: fix_base.h:1027
virtual void sample(const double s, const bool overflow=false)
Register a sample and flag for overflow.
Definition: misc_stat.h:68
Definitions of a base class for fixed-point data types.
#define it_error(s)
Abort unconditionally.
Definition: itassert.h:126
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
Definition: itassert.h:107
const int MAX_WORDLEN
Max word length.
Definition: fix_base.h:886
const double DOUBLE_POW2[128]
Table for fast multiplication by 2^(n-64)
Definition: fix_base.h:906
const uint64_t UINT64_POW2[64]
Table for fast multiplication or division by 2^n.
Definition: fix_base.h:889
q_mode
Quantization modes (aligned with SystemC)
Definition: fix_base.h:957
output_mode
Output modes.
Definition: fix_base.h:969
int64_t fixrep
Representation for fixed-point data types.
Definition: fix_base.h:884
@ SAT
Saturation.
Definition: fix_base.h:949
@ WRAP
Wrap-around.
Definition: fix_base.h:952
@ US
Unsigned.
Definition: fix_base.h:944
@ TC
Two's complement.
Definition: fix_base.h:943
@ TRN
Truncation.
Definition: fix_base.h:964
@ TRN_ZERO
Truncation to zero.
Definition: fix_base.h:965
@ RND
Rounding to plus infinity.
Definition: fix_base.h:958
@ RND_INF
Rounding to infinity.
Definition: fix_base.h:961
@ RND_CONV
Convergent rounding with half-way value rounded to even value.
Definition: fix_base.h:962
@ RND_MIN_INF
Rounding to minus infinity.
Definition: fix_base.h:960
@ RND_ZERO
Rounding to zero.
Definition: fix_base.h:959
@ RND_CONV_ODD
Convergent rounding with half-way value rounded to odd value (not defined in SystemC)
Definition: fix_base.h:963
@ OUTPUT_FIX
Output fixed-point representation only.
Definition: fix_base.h:970
@ OUTPUT_FLOAT
Output floating-point value.
Definition: fix_base.h:972
@ OUTPUT_FIX_SHIFT
Output fixed-point representation followed by <shift> (default)
Definition: fix_base.h:971
@ OUTPUT_FLOAT_SHIFT
Output floating-point value followed by <<shift.
Definition: fix_base.h:973
Error handling functions - header file.
itpp namespace
Definition: itmex.h:37
ITPP_EXPORT double round(double x)
Round to nearest integer, return result in double.
SourceForge Logo

Generated on Tue Jan 24 2023 00:00:00 for IT++ by Doxygen 1.9.6