2 Copyright (c) 2002-2009 Tampere University.
4 This file is part of TTA-Based Codesign Environment (TCE).
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:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
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.
27 * Inline implementations.
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)
37 #include "Exception.hh"
38 #include "MathTools.hh"
39 #include "BaseType.hh"
42 * Returns the number of bits required to represent the given (nonzero) number
43 * as an unsigned number. Gives result(1) for 0.
45 * @note assumes that integers are stored as 2's complement.
47 * @param number The number.
48 * @return The number of bits required to represent the given number.
51 MathTools::requiredBits(unsigned long int number) {
55 return requiredBits0Bit0(number);
60 * Returns the number of bits required to represent the given number
61 * as an unsigned number. Gives result(0) for 0.
64 MathTools::requiredBits0Bit0(long unsigned int number) {
65 unsigned int bits = 0;
74 * Returns ceiling of base-2 logarithm of given number as integer.
77 MathTools::ceil_log2(long unsigned int number) {
78 return static_cast<int>(ceil(log(number)/log(2.0)));
82 * Returns ceiling of divided numbers as integer.
84 template<typename NumberType>
86 MathTools::ceil_div(NumberType dividee, NumberType diveder) {
87 return static_cast<int>(ceil((double) dividee / (double) diveder));
93 * Returns the number of bits required to represent the given number as
96 * @note assumes that integers are stored as 2's complement.
98 * @param number The number.
99 * @return The number of bits required to represent the given number.
103 MathTools::requiredBitsSigned(SLongWord number) {
105 while (number != -1 && number != 0) {
106 number = number >> 1;
113 * Returns the number of bits required to represent the given number as
116 * @note assumes that integers are stored as 2's complement.
118 * @param number The number.
119 * @return The number of bits required to represent the given number.
123 MathTools::requiredBitsSigned(UInt32 number) {
125 // first cast to a signed type
126 int32_t numberSigned = static_cast<int32_t>(number);
127 return requiredBitsSigned(static_cast<SLongWord>(numberSigned));
131 * Returns the number of bits required to represent the given number as
134 * @note assumes that integers are stored as 2's complement.
136 * @param number The number.
137 * @return The number of bits required to represent the given number.
141 MathTools::requiredBitsSigned(int number) {
143 return requiredBitsSigned(static_cast<SLongWord>(number));
147 * Returns the number of bits required to represent the given number as
150 * @note assumes that integers are stored as 2's complement.
152 * @param number The number.
153 * @return The number of bits required to represent the given number.
157 MathTools::requiredBitsSigned(ULongWord number) {
158 return requiredBitsSigned(static_cast<SLongWord>(number));
162 * Returns the number of bits required to represent the give number as
163 * an unsigned number. 0 is implicit 0.
165 * @note assumes that integers are stored as 2's complement.
167 * @param number The number.
168 * @return The number of bits required to represent the given number.
171 MathTools::bitLength(long unsigned int number) {
172 unsigned int bits = 0;
173 while (number != 0) {
174 number = number >> 1;
182 * Compares bit fields (binary encoded) of enc1 and enc2.
186 * ->| |<-----| pos1 = 6
187 * 00001101011011| enc1 = 859 => 1101
188 * 00001011110100| enc2 = 756 => = 1101
189 * ->| |<-| pos2 = 2 ---------
190 * --------------- width = 4 true
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.
201 MathTools::bitFieldsEquals(
202 unsigned enc1, unsigned pos1,
203 unsigned enc2, unsigned pos2,
209 enc1 = enc1 & ~(~(0u) << width);
210 enc2 = enc2 & ~(~(0u) << width);
218 * Returns the value of the bit at a given position in an integer.
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.
225 MathTools::bit(ULongWord integer, unsigned int index) {
226 return (integer & (1 << index)) != 0;
231 * Sets or clears bit at the index.
233 * @param bits The bits.
234 * @param index The index of the bit starting from zero. The bits are indexed
236 * @param bitState The state of the bit to be set. By default sets bit to one.
238 template<class IntegerType>
242 IntegerType& bits, unsigned int index, bool bitState) {
244 bits |= IntegerType(1) << index;
246 bits &= ~(IntegerType(1) << index);
252 * Chops a signed integer number to a given bit width.
254 * Overwrites all bits that do not fit in the given bit width with the sign
255 * bit (the bit at position width - 1).
257 * This operation corresponds to reinterpreting the given number as a signed
258 * word of given bit width.
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
266 MathTools::signExtendTo(SLongWord value, int width) {
268 int bitsInInt = sizeof(value) * BYTE_BITWIDTH;
269 if (width > bitsInInt) {
270 throw OutOfRange(__FILE__, __LINE__, __func__);
273 value = value << (bitsInInt - width);
274 value = value >> (bitsInInt - width);
281 * Chops an unsigned integer number to a given bit width.
283 * Overwrites all bits that do not fit in the given bit width with zero.
285 * This operation corresponds to reinterpreting the given number as an
286 * unsigned word of given bit width.
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
294 MathTools::zeroExtendTo(ULongWord value, int width) {
296 int bitsInInt = sizeof(value) * BYTE_BITWIDTH;
297 if (width > bitsInInt) {
298 throw OutOfRange(__FILE__, __LINE__, __func__);
301 // and with a mask with only the lower 'width' bits '1'
302 value = value & (~(ULongWord)0 >> (bitsInInt - width));
309 * Same as signExtendTo, except without additional overhead of exceptions
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.
317 MathTools::fastSignExtendTo(SLongWord value, int width) {
319 const int bitsInInt = sizeof(SLongWord) * BYTE_BITWIDTH;
321 value = value << (bitsInInt - width);
322 value = value >> (bitsInInt - width);
329 * Same as zeroExtendTo, except without additional overhead of exceptions
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.
337 MathTools::fastZeroExtendTo(ULongWord value, int width) {
339 const int bitsInInt = sizeof(value) * BYTE_BITWIDTH;
341 // and with a mask with only the lower 'width' bits '1'
342 value = value & (~(ULongWord)0 >> (bitsInInt - width));
349 * Returns a random number between range min..max
351 * @param min minimum value
352 * @param max maximum value
353 * @return The generated pseudo-random number
356 MathTools::random(int min, int max) {
357 static bool initialized = false;
362 return (rand() % (max - min + 1)) + min;
366 * Rounds a number upwards to a number which is of power-2.
369 MathTools::roundUpToPowerTwo(unsigned int number) {
374 for (; (1u << i) < number; i++) ;
379 * Rounds a number downwards to a number which is of power-2.
382 MathTools::roundDownToPowerTwo(ULongWord number) {
387 for (; 1lu << i <= number; i++) ;
388 return (1lu<<i) >> 1;
392 * Rounds a number upwards to a number which is of power-2.
395 MathTools::roundUpToPowerTwo(int number) {
396 return static_cast<int>(roundUpToPowerTwo(
397 static_cast<unsigned int>(number)));
401 * Rounds a number downwards to a number which is of power-2.
404 MathTools::roundDownToPowerTwo(SLongWord number) {
405 return static_cast<SLongWord>(roundDownToPowerTwo(
406 static_cast<ULongWord>(number)));
411 * Returns true if the number is in set of 2^i where i is positive integer.
414 MathTools::isInPowerOfTwo(unsigned int number) {
415 std::bitset<sizeof(unsigned int)*8> bits(number);
416 return bits.count() == 1;
421 * Return integer range that can be expressed by a binary field.
423 * The template argument must implement:
424 * - ResultNumberType(0), ResultNumberType(1),
425 * - (-ResultNumberType) -> ResultNumberType,
426 * - (ResultNumberType << unsigned) -> ResultNumberType and
427 * - (ResultNumberType - int) -> ResultNumberType
429 template<typename ResultNumberTypeS, typename ResultNumberTypeU>
430 inline std::pair<ResultNumberTypeS, ResultNumberTypeU>
431 MathTools::bitsToIntegerRange(
432 unsigned bitWidth, bool signExtending) {
435 return std::make_pair(ResultNumberTypeS(0), ResultNumberTypeU(0));
438 // Todo needs different handling when
439 // bitWidth == bitWidth(ResultNumberType)
441 ResultNumberTypeS currLowerBound(0);
442 ResultNumberTypeU currUpperBound(0);
444 currLowerBound = -(ResultNumberTypeS(1) << (bitWidth-1));
445 currUpperBound = (ResultNumberTypeU(1) << (bitWidth-1))-1;
447 currUpperBound = (ResultNumberTypeU(1) << (bitWidth))-1;
449 return std::make_pair(currLowerBound, currUpperBound);