TBTK
Need a break? Support the development by playing Polarity Puzzles
ExtensiveBitRegister.h
Go to the documentation of this file.
1 /* Copyright 2016 Kristofer Björnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
23 #ifndef COM_DAFER45_TBTK_EXTENSIVE_BIT_REGISTER
24 #define COM_DAFER45_TBTK_EXTENSIVE_BIT_REGISTER
25 
26 #include "TBTK/Streams.h"
27 #include "TBTK/TBTKMacros.h"
28 
29 #include <climits>
30 
31 namespace TBTK{
32 
44 public:
47 
49  ExtensiveBitRegister(unsigned int numBits);
50 
52  ExtensiveBitRegister(const ExtensiveBitRegister &extensiveBitRegister);
53 
56 
59  const ExtensiveBitRegister &rhs
60  ) const;
61 
64  const ExtensiveBitRegister &rhs
65  ) const;
66 
69  const ExtensiveBitRegister &rhs
70  ) const;
71 
74  const ExtensiveBitRegister &rhs
75  ) const;
76 
79  const ExtensiveBitRegister &rhs
80  ) const;
81 
83  bool operator<(const ExtensiveBitRegister &rhs) const;
84 
86  bool operator>(const ExtensiveBitRegister &rhs) const;
87 
89  bool operator==(const ExtensiveBitRegister &rhs) const;
90 
92  void operator+=(const ExtensiveBitRegister &rhs);
93 
95  void operator-=(const ExtensiveBitRegister &rhs);
96 
99 
101  const ExtensiveBitRegister operator++(int);
102 
105 
107  const ExtensiveBitRegister operator--(int);
108 
110  void operator=(const ExtensiveBitRegister &rhs);
111 
113  void operator=(const unsigned int rhs);
114 
116  ExtensiveBitRegister operator<<(unsigned int rhs) const;
117 
119  ExtensiveBitRegister operator>>(unsigned int rhs) const;
120 
122  void setBit(unsigned int position, bool values);
123 
125  bool getBit(unsigned int position) const;
126 
129  bool toBool() const;
130 
133  unsigned int toUnsignedInt() const;
134 
136  void clear();
137 
139  void print() const;
140 
142  unsigned int getNumBits() const;
143 
145  unsigned int getNumOneBits() const;
146 
148  bool getMostSignificantBit() const;
149 
151  void setMostSignificantBit();
152 
155 
158 
162  std::string toString() const;
163 
171  friend std::ostream& operator<<(
172  std::ostream &stream,
173  const ExtensiveBitRegister &extensiveBitRegister
174  );
175 private:
177  unsigned int size;
178 
180  unsigned int *values;
181 
183  static constexpr unsigned int MOST_SIGNIFICANT_BIT_MASK
184  = (unsigned int)0x1 << (8*sizeof(unsigned int) - 1);
185 };
186 
188  const ExtensiveBitRegister &rhs
189 ) const{
190  TBTKAssert(
191  size == rhs.size,
192  "ExtensiveBitRegister::operator|()",
193  "Incompatible register sizes.",
194  ""
195  );
196 
198  for(unsigned int n = 0; n < size; n++)
199  result.values[n] = values[n] | rhs.values[n];
200 
201  return result;
202 }
203 
205  const ExtensiveBitRegister &rhs
206 ) const{
207  TBTKAssert(
208  size == rhs.size,
209  "ExtensiveBitRegister::operator|()",
210  "Incompatible register sizes.",
211  ""
212  );
213 
215  for(unsigned int n = 0; n < size; n++)
216  result.values[n] = values[n] & rhs.values[n];
217 
218  return result;
219 }
220 
222  const ExtensiveBitRegister &rhs
223 ) const{
224  TBTKAssert(
225  size == rhs.size,
226  "ExtensiveBitRegister::operator|()",
227  "Incompatible register sizes.",
228  ""
229  );
230 
232  for(unsigned int n = 0; n < size; n++)
233  result.values[n] = values[n] ^ rhs.values[n];
234 
235  return result;
236 }
237 
239  const ExtensiveBitRegister &rhs
240 ) const{
241  TBTKAssert(
242  size == rhs.size,
243  "ExtensiveBitRegister::operator+()",
244  "Incompatible register sizes.",
245  ""
246  );
247 
249  unsigned int carry = 0;
250  for(unsigned int n = 0; n < size; n++){
251  result.values[n] = values[n] + rhs.values[n];
252  unsigned int newCarry = (result.values[n] < values[n]);
253  result.values[n] += carry;
254  carry = newCarry | (result.values[n] < values[n]);
255  }
256 
257  return result;
258 }
259 
261  const ExtensiveBitRegister &rhs
262 ) const{
263  TBTKAssert(
264  size == rhs.size,
265  "ExtensiveBitRegister::operator+()",
266  "Incompatible register sizes.",
267  ""
268  );
269 
271  unsigned int carry = 0;
272  for(unsigned int n = 0; n < size; n++){
273  result.values[n] = values[n] - rhs.values[n];
274  unsigned int newCarry = (result.values[n] > values[n]);
275  result.values[n] -= carry;
276  carry = newCarry | (result.values[n] > values[n]);
277  }
278 
279  return result;
280 }
281 
283  const ExtensiveBitRegister &rhs
284 ) const{
285  for(int n = size-1; n >= 0; n--){
286  if(values[n] < rhs.values[n])
287  return true;
288  if(values[n] > rhs.values[n])
289  return false;
290  }
291 
292  return false;
293 }
294 
296  const ExtensiveBitRegister &rhs
297 ) const{
298  for(int n = size-1; n >= 0; n--){
299  if(values[n] > rhs.values[n])
300  return true;
301  if(values[n] < rhs.values[n])
302  return false;
303  }
304 
305  return false;
306 }
307 
309  const ExtensiveBitRegister &rhs
310 ) const{
311  for(unsigned int n = 0; n < size; n++){
312  if(values[n] != rhs.values[n])
313  return false;
314  }
315 
316  return true;
317 }
318 
320  TBTKAssert(
321  size == rhs.size,
322  "ExtensiveBitRegister::operator+=()",
323  "Incompatible register sizes.",
324  ""
325  );
326 
327  unsigned int carry = 0;
328  for(unsigned int n = 0; n < size; n++){
329  unsigned int temp = values[n];
330  values[n] = temp + rhs.values[n];
331  unsigned int newCarry = (values[n] < temp);
332  values[n] += carry;
333  carry = newCarry | (values[n] < temp);
334  }
335 }
336 
338  TBTKAssert(
339  size == rhs.size,
340  "ExtensiveBitRegister::operator-=()",
341  "Incompatible register sizes.",
342  ""
343  );
344 
345  unsigned int carry = 0;
346  for(unsigned int n = 0; n < size; n++){
347  unsigned int temp = values[n];
348  values[n] = temp - rhs.values[n];
349  unsigned int newCarry = (values[n] > temp);
350  values[n] -= carry;
351  carry = newCarry | (values[n] > temp);
352  }
353 }
354 
356  for(unsigned int n = 0; n < size; n++){
357  if(values[n] == UINT_MAX){
358  values[n]++;
359  }
360  else{
361  values[n]++;
362  break;
363  }
364  }
365 
366  return *this;
367 }
368 
370  ExtensiveBitRegister returnValue(*this);
371  ++(*this);
372 
373  return returnValue;
374 }
375 
377  for(unsigned int n = 0; n < size; n++){
378  if(values[n] == 0){
379  values[n]--;
380  }
381  else{
382  values[n]--;
383  break;
384  }
385  }
386 
387  return *this;
388 }
389 
391  ExtensiveBitRegister returnValue(*this);
392  --(*this);
393 
394  return returnValue;
395 }
396 
398  if(this != &rhs){
399  if(values == nullptr){
400  size = rhs.size;
401  values = new unsigned int[size];
402  for(unsigned int n = 0; n < size; n++)
403  values[n] = rhs.values[n];
404  }
405  else{
406  TBTKAssert(
407  size == rhs.size,
408  "ExtensiveBitRegister::operator=()",
409  "Incompatible register sizes.",
410  ""
411  );
412 
413  for(unsigned int n = 0; n < size; n++)
414  values[n] = rhs.values[n];
415  }
416  }
417 }
418 
419 inline void ExtensiveBitRegister::operator=(const unsigned int rhs){
420  values[0] = rhs;
421  for(unsigned int n = 1; n < size; n++)
422  values[n] = 0;
423 }
424 
426  ExtensiveBitRegister result(*this);
427  if(rhs > 8*sizeof(unsigned int)){
428  result = result << (rhs - 8*sizeof(unsigned int));
429 
430  for(int n = size-1; n > 0; n--)
431  result.values[n] = result.values[n-1];
432  result.values[0] = 0;
433  }
434  else if(rhs == 8*sizeof(unsigned int)){
435  for(int n = size-1; n > 0; n--)
436  result.values[n] = result.values[n-1];
437  result.values[0] = 0;
438  }
439  else if(rhs != 0){
440  for(int n = size-1; n >= 0; n--){
441  result.values[n] = result.values[n] << rhs;
442  if(n > 0)
443  result.values[n] |= result.values[n-1] >> (8*sizeof(unsigned int) - rhs);
444  }
445  }
446 
447  return result;
448 }
449 
451  ExtensiveBitRegister result(*this);
452  if(rhs > 8*sizeof(unsigned int)){
453  result = result >> (rhs - 8*sizeof(unsigned int));
454 
455  for(unsigned int n = 0; n < size-1; n++)
456  result.values[n] = result.values[n+1];
457  result.values[size-1] = 0;
458  }
459  else if(rhs != 0){
460  for(unsigned int n = 0; n < size; n++){
461  result.values[n] = result.values[n] >> rhs;
462  if(n < size-1)
463  result.values[n] |= result.values[n+1] << (8*sizeof(unsigned int) - rhs);
464  }
465  }
466 
467  return result;
468 }
469 
470 inline void ExtensiveBitRegister::print() const{
471  for(unsigned int n = size; n > 0; n--){
472  for(int c = 8*sizeof(unsigned int)-1; c >= 0; c--)
473  Streams::out << (0x1 & (values[n-1] >> c));
474  Streams::out << " ";
475  }
476  Streams::out << "\n";
477 }
478 
479 inline void ExtensiveBitRegister::setBit(unsigned int position, bool value){
480  values[position/(8*sizeof(unsigned int))] &= ~(1 << (position%(8*sizeof(unsigned int))));
481  values[position/(8*sizeof(unsigned int))] ^= (value << (position%(8*sizeof(unsigned int))));
482 }
483 
484 inline bool ExtensiveBitRegister::getBit(unsigned int position) const{
485  return (0x1 & (values[position/(8*sizeof(unsigned int))] >> (position%(8*sizeof(unsigned int)))));
486 }
487 
488 inline bool ExtensiveBitRegister::toBool() const{
489  for(unsigned int n = 0; n < size; n++)
490  if(values[n])
491  return true;
492 
493  return false;
494 }
495 
496 inline unsigned int ExtensiveBitRegister::toUnsignedInt() const{
497  return values[0];
498 }
499 
501  for(unsigned int n = 0; n < size; n++)
502  values[n] = 0;
503 }
504 
505 inline unsigned int ExtensiveBitRegister::getNumBits() const{
506  return size*8*sizeof(unsigned int);
507 }
508 
509 inline unsigned int ExtensiveBitRegister::getNumOneBits() const{
510  unsigned int numOnes = 0;
511  for(unsigned int n = 0; n < size; n++){
512  unsigned int x = values[n];
513  x = x - ((x >> 1) & 0x55555555);
514  x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
515  x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
516  x = x + (x >> 8);
517  x = x + (x >> 16);
518  numOnes += (x & 0x0000003F);
519  }
520 
521  return numOnes;
522 }
523 
525  return values[size-1] & MOST_SIGNIFICANT_BIT_MASK;
526 }
527 
529  values[size-1] |= MOST_SIGNIFICANT_BIT_MASK;
530 }
531 
533  values[size-1] &= !MOST_SIGNIFICANT_BIT_MASK;
534 }
535 
537  return ExtensiveBitRegister(size*8*sizeof(unsigned int));
538 }
539 
540 inline std::string ExtensiveBitRegister::toString() const{
541  std::stringstream stream;
542  for(unsigned int n = getNumBits(); n > 0; n--)
543  stream << getBit(n - 1);
544 
545  return stream.str();
546 }
547 
548 inline std::ostream& operator<<(
549  std::ostream &stream,
550  const ExtensiveBitRegister &extensiveBitRegister
551 ){
552  stream << extensiveBitRegister.toString();
553 
554  return stream;
555 }
556 
557 }; //End of namespace TBTK
558 
559 #endif
void print() const
Definition: ExtensiveBitRegister.h:470
bool operator<(const ExtensiveBitRegister &rhs) const
Definition: ExtensiveBitRegister.h:282
const ExtensiveBitRegister & operator--()
Definition: ExtensiveBitRegister.h:376
const ExtensiveBitRegister & operator++()
Definition: ExtensiveBitRegister.h:355
ExtensiveBitRegister operator<<(unsigned int rhs) const
Definition: ExtensiveBitRegister.h:425
void setBit(unsigned int position, bool values)
Definition: ExtensiveBitRegister.h:479
void setMostSignificantBit()
Definition: ExtensiveBitRegister.h:528
ExtensiveBitRegister cloneStructure() const
Definition: ExtensiveBitRegister.h:536
Precompiler macros.
const ExtensiveBitRegister operator &(const ExtensiveBitRegister &rhs) const
std::string toString() const
Definition: ExtensiveBitRegister.h:540
const ExtensiveBitRegister operator+(const ExtensiveBitRegister &rhs) const
Definition: ExtensiveBitRegister.h:238
bool toBool() const
Definition: ExtensiveBitRegister.h:488
const ExtensiveBitRegister operator-(const ExtensiveBitRegister &rhs) const
Definition: ExtensiveBitRegister.h:260
bool getBit(unsigned int position) const
Definition: ExtensiveBitRegister.h:484
bool operator>(const ExtensiveBitRegister &rhs) const
Definition: ExtensiveBitRegister.h:295
bool getMostSignificantBit() const
Definition: ExtensiveBitRegister.h:524
void operator+=(const ExtensiveBitRegister &rhs)
Definition: ExtensiveBitRegister.h:319
void operator-=(const ExtensiveBitRegister &rhs)
Definition: ExtensiveBitRegister.h:337
const ExtensiveBitRegister operator^(const ExtensiveBitRegister &rhs) const
Definition: ExtensiveBitRegister.h:221
static std::ostream out
Definition: Streams.h:70
void clear()
Definition: ExtensiveBitRegister.h:500
Definition: Boolean.h:32
unsigned int getNumBits() const
Definition: ExtensiveBitRegister.h:505
const ExtensiveBitRegister operator|(const ExtensiveBitRegister &rhs) const
Definition: ExtensiveBitRegister.h:187
bool operator==(const ExtensiveBitRegister &rhs) const
Definition: ExtensiveBitRegister.h:308
ExtensiveBitRegister operator>>(unsigned int rhs) const
Definition: ExtensiveBitRegister.h:450
unsigned int toUnsignedInt() const
Definition: ExtensiveBitRegister.h:496
Register of bits.
Definition: ExtensiveBitRegister.h:43
Streams for TBTK output.
void operator=(const ExtensiveBitRegister &rhs)
Definition: ExtensiveBitRegister.h:397
unsigned int getNumOneBits() const
Definition: ExtensiveBitRegister.h:509
void clearMostSignificantBit()
Definition: ExtensiveBitRegister.h:532