OpenASIP  2.0
MathTools.icc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file MathTools.icc
26  *
27  * Inline implementations.
28  *
29  * @author Ari Metsähalme 2005 (ari.metsahalme-no.spam-tut.fi)
30  * @author Pekka Jääskeläinen 2006 (pekka.jaaskelainen-no.spam-tut.fi)
31  */
32 
33 #include <cstdlib>
34 #include <bitset>
35 #include <cmath>
36 #include <ctime>
37 #include "Exception.hh"
38 #include "MathTools.hh"
39 #include "BaseType.hh"
40 
41 /**
42  * Returns the number of bits required to represent the given (nonzero) number
43  * as an unsigned number. Gives result(1) for 0.
44  *
45  * @note assumes that integers are stored as 2's complement.
46  *
47  * @param number The number.
48  * @return The number of bits required to represent the given number.
49  */
50 inline int
51 MathTools::requiredBits(unsigned long int number) {
52  if (number == 0) {
53  return 1;
54  } else {
55  return requiredBits0Bit0(number);
56  }
57 }
58 
59 /**
60  * Returns the number of bits required to represent the given number
61  * as an unsigned number. Gives result(0) for 0.
62  */
63 inline int
64 MathTools::requiredBits0Bit0(long unsigned int number) {
65  unsigned int bits = 0;
66  while (number != 0) {
67  number = number >> 1;
68  bits++;
69  }
70  return bits;
71 }
72 
73 /**
74  * Returns ceiling of base-2 logarithm of given number as integer.
75  */
76 inline int
77 MathTools::ceil_log2(long unsigned int number) {
78  return static_cast<int>(ceil(log(number)/log(2.0)));
79 }
80 
81 /**
82  * Returns ceiling of divided numbers as integer.
83  */
84 template<typename NumberType>
85 inline int
86 MathTools::ceil_div(NumberType dividee, NumberType diveder) {
87  return static_cast<int>(ceil((double) dividee / (double) diveder));
88 }
89 
90 
91 
92 /**
93  * Returns the number of bits required to represent the given number as
94  * a signed integer.
95  *
96  * @note assumes that integers are stored as 2's complement.
97  *
98  * @param number The number.
99  * @return The number of bits required to represent the given number.
100  */
101 
102 inline int
103 MathTools::requiredBitsSigned(SLongWord number) {
104  int bits = 1;
105  while (number != -1 && number != 0) {
106  number = number >> 1;
107  bits++;
108  }
109  return bits;
110 }
111 
112 /**
113  * Returns the number of bits required to represent the given number as
114  * a signed integer.
115  *
116  * @note assumes that integers are stored as 2's complement.
117  *
118  * @param number The number.
119  * @return The number of bits required to represent the given number.
120  */
121 
122 inline int
123 MathTools::requiredBitsSigned(UInt32 number) {
124 
125  // first cast to a signed type
126  int32_t numberSigned = static_cast<int32_t>(number);
127  return requiredBitsSigned(static_cast<SLongWord>(numberSigned));
128 }
129 
130 /**
131  * Returns the number of bits required to represent the given number as
132  * a signed integer.
133  *
134  * @note assumes that integers are stored as 2's complement.
135  *
136  * @param number The number.
137  * @return The number of bits required to represent the given number.
138  */
139 
140 inline int
141 MathTools::requiredBitsSigned(int number) {
142 
143  return requiredBitsSigned(static_cast<SLongWord>(number));
144 }
145 
146 /**
147  * Returns the number of bits required to represent the given number as
148  * a signed integer.
149  *
150  * @note assumes that integers are stored as 2's complement.
151  *
152  * @param number The number.
153  * @return The number of bits required to represent the given number.
154  */
155 
156 inline int
157 MathTools::requiredBitsSigned(ULongWord number) {
158  return requiredBitsSigned(static_cast<SLongWord>(number));
159 }
160 
161 /**
162  * Returns the number of bits required to represent the give number as
163  * an unsigned number. 0 is implicit 0.
164  *
165  * @note assumes that integers are stored as 2's complement.
166  *
167  * @param number The number.
168  * @return The number of bits required to represent the given number.
169  */
170 inline unsigned int
171 MathTools::bitLength(long unsigned int number) {
172  unsigned int bits = 0;
173  while (number != 0) {
174  number = number >> 1;
175  bits++;
176  }
177  return bits;
178 }
179 
180 
181 /**
182  * Compares bit fields (binary encoded) of enc1 and enc2.
183  *
184  * @verbatim
185  * Example:
186  * ->| |<-----| pos1 = 6
187  * 00001101011011| enc1 = 859 => 1101
188  * 00001011110100| enc2 = 756 => = 1101
189  * ->| |<-| pos2 = 2 ---------
190  * --------------- width = 4 true
191  * @endverbatim
192  *
193  * @param enc1 The first binary encoded bit field.
194  * @param pos1 The first LSB bit from right of the enc1.
195  * @param enc2 The second binary encoded bit field.
196  * @param pos2 The first LSB bit from right of the enc2.
197  * @param width The number of bits considered in the comparison.
198  * @return True if the fields do match. Otherwise, false.
199  */
200 inline bool
201 MathTools::bitFieldsEquals(
202  unsigned enc1, unsigned pos1,
203  unsigned enc2, unsigned pos2,
204  unsigned width) {
205 
206  if (width) {
207  enc1 = enc1 >> pos1;
208  enc2 = enc2 >> pos2;
209  enc1 = enc1 & ~(~(0u) << width);
210  enc2 = enc2 & ~(~(0u) << width);
211  return enc1 == enc2;
212  }
213  return false;
214 }
215 
216 
217 /**
218  * Returns the value of the bit at a given position in an integer.
219  *
220  * @param integer The integer.
221  * @param index Indicates which bit should be returned (0 = LSB).
222  * @return The value of the bit indicated by the given index.
223  */
224 inline bool
225 MathTools::bit(ULongWord integer, unsigned int index) {
226  return (integer & (1 << index)) != 0;
227 }
228 
229 
230 /**
231  * Sets or clears bit at the index.
232  *
233  * @param bits The bits.
234  * @param index The index of the bit starting from zero. The bits are indexed
235  * from LSB.
236  * @param bitState The state of the bit to be set. By default sets bit to one.
237  */
238 template<class IntegerType>
239 inline
240 void
241 MathTools::setBit(
242  IntegerType& bits, unsigned int index, bool bitState) {
243  if (bitState) {
244  bits |= IntegerType(1) << index;
245  } else {
246  bits &= ~(IntegerType(1) << index);
247  }
248 }
249 
250 
251 /**
252  * Chops a signed integer number to a given bit width.
253  *
254  * Overwrites all bits that do not fit in the given bit width with the sign
255  * bit (the bit at position width - 1).
256  *
257  * This operation corresponds to reinterpreting the given number as a signed
258  * word of given bit width.
259  *
260  * @param value A signed integer.
261  * @param width Number of meaningful bits in the given integer.
262  * @return The sign-extended value of the integer.
263  * @exception OutOfRange If width > integer size
264  */
265 inline SLongWord
266 MathTools::signExtendTo(SLongWord value, int width) {
267 
268  int bitsInInt = sizeof(value) * BYTE_BITWIDTH;
269  if (width > bitsInInt) {
270  throw OutOfRange(__FILE__, __LINE__, __func__);
271  }
272 
273  value = value << (bitsInInt - width);
274  value = value >> (bitsInInt - width);
275 
276  return value;
277 }
278 
279 
280 /**
281  * Chops an unsigned integer number to a given bit width.
282  *
283  * Overwrites all bits that do not fit in the given bit width with zero.
284  *
285  * This operation corresponds to reinterpreting the given number as an
286  * unsigned word of given bit width.
287  *
288  * @param value An unsigned integer.
289  * @param width Number of meaningful bits in the given integer.
290  * @return The zero-extended value of the integer.
291  * @exception OutOfRange If width > integer size
292  */
293 inline ULongWord
294 MathTools::zeroExtendTo(ULongWord value, int width) {
295 
296  int bitsInInt = sizeof(value) * BYTE_BITWIDTH;
297  if (width > bitsInInt) {
298  throw OutOfRange(__FILE__, __LINE__, __func__);
299  }
300 
301  // and with a mask with only the lower 'width' bits '1'
302  value = value & (~(ULongWord)0 >> (bitsInInt - width));
303 
304  return value;
305 }
306 
307 
308 /**
309  * Same as signExtendTo, except without additional overhead of exceptions
310  *
311  * @param value A signed integer.
312  * @param width Number of meaningful bits in the given integer.
313  * @note width must not exceed int bitwidth!
314  * @return The sign-extended value of the integer.
315  */
316 inline SLongWord
317 MathTools::fastSignExtendTo(SLongWord value, int width) {
318 
319  const int bitsInInt = sizeof(SLongWord) * BYTE_BITWIDTH;
320 
321  value = value << (bitsInInt - width);
322  value = value >> (bitsInInt - width);
323 
324  return value;
325 }
326 
327 
328 /**
329  * Same as zeroExtendTo, except without additional overhead of exceptions
330  *
331  * @param value An unsigned integer.
332  * @param width Number of meaningful bits in the given integer.
333  * @note width must not exceed int bitwidth!
334  * @return The zero-extended value of the integer.
335  */
336 inline ULongWord
337 MathTools::fastZeroExtendTo(ULongWord value, int width) {
338 
339  const int bitsInInt = sizeof(value) * BYTE_BITWIDTH;
340 
341  // and with a mask with only the lower 'width' bits '1'
342  value = value & (~(ULongWord)0 >> (bitsInInt - width));
343 
344  return value;
345 }
346 
347 
348 /**
349  * Returns a random number between range min..max
350  *
351  * @param min minimum value
352  * @param max maximum value
353  * @return The generated pseudo-random number
354  */
355 inline int
356 MathTools::random(int min, int max) {
357  static bool initialized = false;
358  if (!initialized) {
359  srand(std::time(0));
360  initialized = true;
361  }
362  return (rand() % (max - min + 1)) + min;
363 }
364 
365 /**
366  * Rounds a number upwards to a number which is of power-2.
367  */
368 inline unsigned int
369 MathTools::roundUpToPowerTwo(unsigned int number) {
370  unsigned int i = 0;
371  if (number == 0) {
372  return 0;
373  }
374  for (; (1u << i) < number; i++) ;
375  return (1u << i);
376 }
377 
378 /**
379  * Rounds a number downwards to a number which is of power-2.
380  */
381 inline ULongWord
382 MathTools::roundDownToPowerTwo(ULongWord number) {
383  ULongWord i = 0;
384  if (number == 0) {
385  return 0;
386  }
387  for (; 1lu << i <= number; i++) ;
388  return (1lu<<i) >> 1;
389 }
390 
391 /**
392  * Rounds a number upwards to a number which is of power-2.
393  */
394 inline int
395 MathTools::roundUpToPowerTwo(int number) {
396  return static_cast<int>(roundUpToPowerTwo(
397  static_cast<unsigned int>(number)));
398 }
399 
400 /**
401  * Rounds a number downwards to a number which is of power-2.
402  */
403 inline SLongWord
404 MathTools::roundDownToPowerTwo(SLongWord number) {
405  return static_cast<SLongWord>(roundDownToPowerTwo(
406  static_cast<ULongWord>(number)));
407 }
408 
409 
410 /**
411  * Returns true if the number is in set of 2^i where i is positive integer.
412  */
413 inline bool
414 MathTools::isInPowerOfTwo(unsigned int number) {
415  std::bitset<sizeof(unsigned int)*8> bits(number);
416  return bits.count() == 1;
417 }
418 
419 
420 /**
421  * Return integer range that can be expressed by a binary field.
422  *
423  * The template argument must implement:
424  * - ResultNumberType(0), ResultNumberType(1),
425  * - (-ResultNumberType) -> ResultNumberType,
426  * - (ResultNumberType << unsigned) -> ResultNumberType and
427  * - (ResultNumberType - int) -> ResultNumberType
428  */
429 template<typename ResultNumberTypeS, typename ResultNumberTypeU>
430 inline std::pair<ResultNumberTypeS, ResultNumberTypeU>
431 MathTools::bitsToIntegerRange(
432  unsigned bitWidth, bool signExtending) {
433 
434  if (bitWidth == 0) {
435  return std::make_pair(ResultNumberTypeS(0), ResultNumberTypeU(0));
436  }
437 
438  // Todo needs different handling when
439  // bitWidth == bitWidth(ResultNumberType)
440 
441  ResultNumberTypeS currLowerBound(0);
442  ResultNumberTypeU currUpperBound(0);
443  if (signExtending) {
444  currLowerBound = -(ResultNumberTypeS(1) << (bitWidth-1));
445  currUpperBound = (ResultNumberTypeU(1) << (bitWidth-1))-1;
446  } else {
447  currUpperBound = (ResultNumberTypeU(1) << (bitWidth))-1;
448  }
449  return std::make_pair(currLowerBound, currUpperBound);
450 }
451