1 #include "cBitArray.h"
2 
Copy(const cRawBitArray & in_array,const int num_bits)3 void cRawBitArray::Copy(const cRawBitArray & in_array, const int num_bits)
4 {
5   const int num_fields = GetNumFields(num_bits);
6   if (bit_fields != NULL) {
7     delete [] bit_fields;
8   }
9   bit_fields = new unsigned int[num_fields];
10   for (int i = 0; i < num_fields; i++) {
11     bit_fields[i] = in_array.bit_fields[i];
12   }
13 }
14 
15 
IsEqual(const cRawBitArray & in_array,int num_bits) const16 bool cRawBitArray::IsEqual(const cRawBitArray & in_array, int num_bits) const
17 {
18   const int num_fields = GetNumFields(num_bits);
19   for (int i = 0; i < num_fields; i++) {
20     if (bit_fields[i] != in_array.bit_fields[i]) return false;
21   }
22   return true;
23 }
24 
25 
Resize(const int old_bits,const int new_bits)26 void cRawBitArray::Resize(const int old_bits, const int new_bits)
27 {
28   const int num_old_fields = GetNumFields(old_bits);
29   const int num_new_fields = GetNumFields(new_bits);
30   if (num_old_fields == num_new_fields) {
31     // Clear all bits past the new end and stop.
32     unsigned int & last_field = bit_fields[num_new_fields - 1];
33     for (int i = new_bits; i < old_bits; i++) {
34       const unsigned int clear_bit = i & 31;
35       last_field &= ~(1 << clear_bit);
36     }
37     return;
38   }
39 
40   // If we made it this far, we have to change the number of fields.
41   // Create the new bit array and copy the old one into it.
42   unsigned int * new_bit_fields = new unsigned int[ num_new_fields ];
43   for (int i = 0; i < num_new_fields && i < num_old_fields; i++) {
44     new_bit_fields[i] = bit_fields[i];
45   }
46 
47   // If the old bits are longer, we need to clear the end of the last
48   // bit field.
49   if (num_old_fields > num_new_fields) {
50     unsigned int & last_field = new_bit_fields[num_new_fields - 1];
51     for (int clear_bit=GetFieldPos(new_bits); clear_bit < 32; clear_bit++) {
52       last_field &= ~(1 << clear_bit);
53     }
54   }
55 
56   // If the new bits are longer, clear everything past the end of the old
57   // bits.
58   for (int i = num_old_fields; i < num_new_fields; i++) {
59     new_bit_fields[i] = 0;
60   }
61 
62   if (bit_fields != NULL) {
63     delete [] bit_fields;
64   }
65   bit_fields = new_bit_fields;
66 }
67 
68 
ResizeSloppy(const int new_bits)69 void cRawBitArray::ResizeSloppy(const int new_bits)
70 {
71   const int new_fields = GetNumFields(new_bits);
72   if (bit_fields != NULL) {
73     delete [] bit_fields;
74   }
75   bit_fields = new unsigned int[ new_fields ];
76 }
77 
ResizeClear(const int new_bits)78 void cRawBitArray::ResizeClear(const int new_bits)
79 {
80   ResizeSloppy(new_bits);
81   Zero(new_bits);
82 }
83 
84 
85 // This technique counts the number of bits; it loops through once for each
86 // bit equal to 1.  This is reasonably fast for sparse arrays.
CountBits(const int num_bits) const87 int cRawBitArray::CountBits(const int num_bits) const
88 {
89   const int num_fields = GetNumFields(num_bits);
90   int bit_count = 0;
91 
92   for (int i = 0; i < num_fields; i++) {
93     int temp = bit_fields[i];
94     while (temp != 0) {
95       temp = temp & (temp - 1);
96       bit_count++;
97     }
98   }
99   return bit_count;
100 }
101 
102 // This technique is another way of counting bits; It does a bunch of
103 // clever bit tricks to do it in parallel in each int.
CountBits2(const int num_bits) const104 int cRawBitArray::CountBits2(const int num_bits) const
105 {
106   const int num_fields = GetNumFields(num_bits);
107   int bit_count = 0;
108 
109   for (int i = 0; i < num_fields; i++) {
110     const int  v = bit_fields[i];
111     unsigned int const t1 = v - ((v >> 1) & 0x55555555);
112     unsigned int const t2 = (t1 & 0x33333333) + ((t1 >> 2) & 0x33333333);
113     bit_count += ((t2 + (t2 >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
114   }
115   return bit_count;
116 }
117 
FindBit1(const int num_bits,const int start_pos) const118 int cRawBitArray::FindBit1(const int num_bits, const int start_pos) const
119 {
120   // @CAO -- There are probably better ways to do this with bit tricks.
121   for (int i = start_pos; i < num_bits; i++) {
122     if (GetBit(i) == true) return i;
123   }
124 
125   return -1;
126 }
127 
GetOnes(const int num_bits) const128 tArray<int> cRawBitArray::GetOnes(const int num_bits) const
129 {
130   // @CAO -- There are probably better ways to do this with bit tricks.
131   tArray<int> out_array(CountBits2(num_bits));
132   int cur_pos = 0;
133   for (int i = 0; i < num_bits; i++) {
134     if (GetBit(i) == true) out_array[cur_pos++] = i;
135   }
136 
137   return out_array;
138 }
139 
ShiftLeft(const int num_bits,const int shift_size)140 void cRawBitArray::ShiftLeft(const int num_bits, const int shift_size)
141 {
142   assert(shift_size > 0);
143   int num_fields = GetNumFields(num_bits);
144   int field_shift = shift_size / 32;
145   int bit_shift = shift_size % 32;
146 
147 
148   // acount for field_shift
149   if (field_shift) {
150     for (int i = num_fields - 1; i >= field_shift; i--) {
151       bit_fields[i] = bit_fields[i - field_shift];
152     }
153     for (int i = field_shift - 1; i >= 0; i--) {
154       bit_fields[i] = 0;
155     }
156   }
157 
158 
159   // account for bit_shift
160   int temp = 0;
161   for (int i = 0; i < num_fields; i++) {
162     temp = bit_fields[i] >> (32 - bit_shift);
163     bit_fields[i] <<= bit_shift;
164     if (i > 0) bit_fields[i - 1] |= temp;  // same as += in this case since lower bit_shift bits of bit_fields[i - 1] are all 0 at this point -- any advantage?
165     //could also check for temp != 0 here before assignment -- would that save any time for sparse arrays, or is it always going to be useless?
166   }
167 
168   // mask out any bits that have left-shifted away, allowing CountBits and CountBits2 to work
169   // blw: if CountBits/CountBits2 are fixed, this code should be removed as it will be redundant
170   unsigned int shift_mask = 0xFFFFFFFF >> ((32 - (num_bits % 32)) & 0x1F);
171   bit_fields[num_fields - 1] &= shift_mask;
172 }
173 
174 // ALWAYS shifts in zeroes, irrespective of sign bit (since fields are unsigned)
ShiftRight(const int num_bits,const int shift_size)175 void cRawBitArray::ShiftRight(const int num_bits, const int shift_size)
176 {
177   assert(shift_size > 0);
178   int num_fields = GetNumFields(num_bits);
179   int field_shift = shift_size / 32;
180   int bit_shift = shift_size % 32;
181 
182   // account for field_shift
183   if (field_shift) {
184     for (int i = 0; i < num_fields - field_shift; i++) {
185       bit_fields[i] = bit_fields[i + field_shift];
186     }
187     for(int i = num_fields - field_shift; i < num_fields; i++) {
188       bit_fields[i] = 0;
189     }
190   }
191 
192   // account for bit_shift
193   bit_fields[num_fields - 1] >>= bit_shift;  // drops off right end, may shift in ones if sign bit was set
194   int temp = 0;
195   for (int i = num_fields - 2; i >= 0; i--) {
196     temp = bit_fields[i] << (32 - bit_shift);
197     bit_fields[i] >>= bit_shift;
198     bit_fields[i + 1] |= temp;
199   }
200 }
201 
NOT(const int num_bits)202 void cRawBitArray::NOT(const int num_bits)
203 {
204   const int num_fields = GetNumFields(num_bits);
205   for (int i = 0; i < num_fields; i++) {
206     bit_fields[i] = ~bit_fields[i];
207   }
208 
209   const int last_bit = GetFieldPos(num_bits);
210   if (last_bit > 0) {
211     bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
212   }
213 }
214 
AND(const cRawBitArray & array2,const int num_bits)215 void cRawBitArray::AND(const cRawBitArray & array2, const int num_bits)
216 {
217   const int num_fields = GetNumFields(num_bits);
218   for (int i = 0; i < num_fields; i++) {
219     bit_fields[i] &= array2.bit_fields[i];
220   }
221 }
222 
OR(const cRawBitArray & array2,const int num_bits)223 void cRawBitArray::OR(const cRawBitArray & array2, const int num_bits)
224 {
225   const int num_fields = GetNumFields(num_bits);
226   for (int i = 0; i < num_fields; i++) {
227     bit_fields[i] |= array2.bit_fields[i];
228   }
229 }
230 
NAND(const cRawBitArray & array2,const int num_bits)231 void cRawBitArray::NAND(const cRawBitArray & array2, const int num_bits)
232 {
233   const int num_fields = GetNumFields(num_bits);
234   for (int i = 0; i < num_fields; i++) {
235     bit_fields[i] = ~(bit_fields[i] & array2.bit_fields[i]);
236   }
237 
238   const int last_bit = GetFieldPos(num_bits);
239   if (last_bit > 0) {
240     bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
241   }
242 }
243 
NOR(const cRawBitArray & array2,const int num_bits)244 void cRawBitArray::NOR(const cRawBitArray & array2, const int num_bits)
245 {
246   const int num_fields = GetNumFields(num_bits);
247   for (int i = 0; i < num_fields; i++) {
248     bit_fields[i] = ~(bit_fields[i] | array2.bit_fields[i]);
249   }
250 
251   const int last_bit = GetFieldPos(num_bits);
252   if (last_bit > 0) {
253     bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
254   }
255 }
256 
XOR(const cRawBitArray & array2,const int num_bits)257 void cRawBitArray::XOR(const cRawBitArray & array2, const int num_bits)
258 {
259   const int num_fields = GetNumFields(num_bits);
260   for (int i = 0; i < num_fields; i++) {
261     bit_fields[i] ^= array2.bit_fields[i];
262   }
263 
264 }
265 
EQU(const cRawBitArray & array2,const int num_bits)266 void cRawBitArray::EQU(const cRawBitArray & array2, const int num_bits)
267 {
268   const int num_fields = GetNumFields(num_bits);
269   for (int i = 0; i < num_fields; i++) {
270     bit_fields[i] = ~(bit_fields[i] ^ array2.bit_fields[i]);
271   }
272 
273   const int last_bit = GetFieldPos(num_bits);
274   if (last_bit > 0) {
275     bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
276   }
277 }
278 
SHIFT(const int num_bits,const int shift_size)279 void cRawBitArray::SHIFT(const int num_bits, const int shift_size)
280 {
281   if (shift_size == 0) return;
282   if (shift_size > 0) { ShiftLeft(num_bits, shift_size); return; }
283   if (shift_size < 0) { ShiftRight(num_bits, -shift_size); return; }
284   assert(false); // Should never get here.
285 }
286 
INCREMENT(const int num_bits)287 void cRawBitArray::INCREMENT(const int num_bits)
288 {
289   const int num_fields = GetNumFields(num_bits);
290   int i = 0;
291   for (i = 0; i < num_fields; i++) {
292     bit_fields[i]++;
293     if (bit_fields[i] != 0) { break; }  // no overflow, do not need to increment higher fields
294   }
295 
296   // if highest bit field was incremented, mask out any unused portions of the field so as not to confuse CountBits
297   if (i == num_fields - 1) {
298     unsigned int shift_mask = 0xffffffff >> 32 - (num_bits % 32);
299     bit_fields[num_fields - 1] &= shift_mask;
300   }
301 }
302 
303 
304 
305 
306 
NOT(const cRawBitArray & array1,const int num_bits)307 void cRawBitArray::NOT(const cRawBitArray & array1, const int num_bits)
308 {
309   ResizeSloppy(num_bits);
310 
311   const int num_fields = GetNumFields(num_bits);
312   for (int i = 0; i < num_fields; i++) {
313     bit_fields[i] = ~array1.bit_fields[i];
314   }
315 
316   const int last_bit = GetFieldPos(num_bits);
317   if (last_bit > 0) {
318     bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
319   }
320 }
321 
AND(const cRawBitArray & array1,const cRawBitArray & array2,const int num_bits)322 void cRawBitArray::AND(const cRawBitArray & array1,
323 		       const cRawBitArray & array2, const int num_bits)
324 {
325   ResizeSloppy(num_bits);
326 
327   const int num_fields = GetNumFields(num_bits);
328   for (int i = 0; i < num_fields; i++) {
329     bit_fields[i] = array1.bit_fields[i] & array2.bit_fields[i];
330   }
331 }
332 
OR(const cRawBitArray & array1,const cRawBitArray & array2,const int num_bits)333 void cRawBitArray::OR(const cRawBitArray & array1,
334 		      const cRawBitArray & array2, const int num_bits)
335 {
336   ResizeSloppy(num_bits);
337 
338   const int num_fields = GetNumFields(num_bits);
339   for (int i = 0; i < num_fields; i++) {
340     bit_fields[i] = array1.bit_fields[i] | array2.bit_fields[i];
341   }
342 }
343 
NAND(const cRawBitArray & array1,const cRawBitArray & array2,const int num_bits)344 void cRawBitArray::NAND(const cRawBitArray & array1,
345 			const cRawBitArray & array2, const int num_bits)
346 {
347   ResizeSloppy(num_bits);
348 
349   const int num_fields = GetNumFields(num_bits);
350   for (int i = 0; i < num_fields; i++) {
351     bit_fields[i] = ~(array1.bit_fields[i] & array2.bit_fields[i]);
352   }
353 
354   const int last_bit = GetFieldPos(num_bits);
355   if (last_bit > 0) {
356     bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
357   }
358 }
359 
NOR(const cRawBitArray & array1,const cRawBitArray & array2,const int num_bits)360 void cRawBitArray::NOR(const cRawBitArray & array1,
361 		       const cRawBitArray & array2, const int num_bits)
362 {
363   ResizeSloppy(num_bits);
364 
365   const int num_fields = GetNumFields(num_bits);
366   for (int i = 0; i < num_fields; i++) {
367     bit_fields[i] = ~(array1.bit_fields[i] | array2.bit_fields[i]);
368   }
369 
370   const int last_bit = GetFieldPos(num_bits);
371   if (last_bit > 0) {
372     bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
373   }
374 }
375 
XOR(const cRawBitArray & array1,const cRawBitArray & array2,const int num_bits)376 void cRawBitArray::XOR(const cRawBitArray & array1,
377 		       const cRawBitArray & array2, const int num_bits)
378 {
379   ResizeSloppy(num_bits);
380 
381   const int num_fields = GetNumFields(num_bits);
382   for (int i = 0; i < num_fields; i++) {
383     bit_fields[i] = array1.bit_fields[i] ^ array2.bit_fields[i];
384   }
385 
386 }
387 
EQU(const cRawBitArray & array1,const cRawBitArray & array2,const int num_bits)388 void cRawBitArray::EQU(const cRawBitArray & array1, const cRawBitArray & array2, const int num_bits)
389 {
390   ResizeSloppy(num_bits);
391 
392   const int num_fields = GetNumFields(num_bits);
393   for (int i = 0; i < num_fields; i++) {
394     bit_fields[i] = ~(array1.bit_fields[i] ^ array2.bit_fields[i]);
395   }
396 
397   const int last_bit = GetFieldPos(num_bits);
398   if (last_bit > 0) {
399     bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
400   }
401 }
402 
SHIFT(const cRawBitArray & array1,const int num_bits,const int shift_size)403 void cRawBitArray::SHIFT(const cRawBitArray & array1, const int num_bits, const int shift_size)
404 {
405   if (shift_size == 0) return;
406 
407   Copy(array1, num_bits);
408 
409   SHIFT(num_bits, shift_size);
410 }
411 
INCREMENT(const cRawBitArray & array1,const int num_bits)412 void cRawBitArray::INCREMENT(const cRawBitArray & array1, const int num_bits)
413 {
414   Copy(array1, num_bits);
415   INCREMENT(num_bits);
416 }
417 
418 
419 
420 
operator <<(std::ostream & out,const cBitArray & bit_array)421 std::ostream & operator << (std::ostream & out, const cBitArray & bit_array)
422 {
423   bit_array.Print(out);
424   return out;
425 }
426 
427 
428 
429 #ifdef UNITTEST_CBITARRAY
430 
main()431 int main()
432 {
433   int passed = true;
434   // Start by testing the cRawBitArray class.
435 
436   // Test default constructor.
437   cRawBitArray bit_array1;
438   bit_array1.ResizeClear(10);
439   for (int i = 0; i < 10; i++) {
440     if (bit_array1.GetBit(i) != false) {
441       passed = false;
442       cerr << "ERROR in testing bit that should be cleared by ResizeClear()!"
443 	   << endl;
444     }
445   }
446 
447   //bit_array1.Print(10);
448 
449   bit_array1.SetBit(1, true);
450   bit_array1.SetBit(3, true);
451   bit_array1.SetBit(5, true);
452   bit_array1.SetBit(7, true);
453   bit_array1.SetBit(9, true);
454 
455   for (int i = 0; i < 10; i++) {
456     bool bit_value = !(2*(i/2) == i);
457     if (bit_array1.GetBit(i) != bit_value) {
458       passed = false;
459       cerr << "ERROR in testing bits after SetBit() was run on them!"
460 	   << endl;
461     }
462   }
463 
464   //bit_array1.Print(10);
465   bit_array1.SetBit(0, true);
466   bit_array1.SetBit(1, false);
467   bit_array1.SetBit(5, false);
468   bit_array1.SetBit(6, true);
469   bit_array1.SetBit(7, false);
470   //bit_array1.Print(10);
471 
472   for (int i = 0; i < 10; i++) {
473     bool bit_value = (3*(i/3) == i);
474     if (bit_array1.GetBit(i) != bit_value) {
475       passed = false;
476       cerr << "ERROR in testing bits after second round of SetBit() was run!"
477 	   << endl;
478     }
479   }
480 
481   // Test constructor with initial size < 32.
482   cRawBitArray bit_array2(26);
483   for (int i = 0; i < 26; i++) {
484     if (bit_array2.GetBit(i) != false) {
485       passed = false;
486       cerr << "ERROR in testing bit that should be cleared by constructor()!"
487 	   << endl;
488     }
489   }
490   bit_array2.SetBit(8, true);
491   bit_array2.Copy(bit_array1, 10);
492 
493   for (int i = 0; i < 10; i++) {
494     bool bit_value = (3*(i/3) == i);
495     if (bit_array2.GetBit(i) != bit_value) {
496       passed = false;
497       cerr << "ERROR in testing bits after Copy()!"
498 	   << endl;
499     }
500   }
501 
502   // Test constructor with initial size > 32.
503   const int high_bit_count = 1000;
504   cRawBitArray bit_array3(high_bit_count);
505   int bit_pos = 2;
506   while (bit_pos < high_bit_count) {
507     bit_array3.SetBit(bit_pos, true);
508     bit_pos = bit_pos * 3 / 2;
509   }
510 
511   // Test faux copy constructor.
512   cRawBitArray bit_array4(bit_array3, high_bit_count);
513   bit_array4.SetBit(22, true);
514   bit_array4.SetBit(24, true);
515   int count1 =  bit_array3.CountBits(high_bit_count);
516   int count2 =  bit_array3.CountBits2(high_bit_count);
517   int count3 =  bit_array4.CountBits(high_bit_count);
518   int count4 =  bit_array4.CountBits2(high_bit_count);
519 
520   if (count1 != count2 || count3 != count4) {
521     passed = false;
522     cerr << "ERROR: CountBits and CountBits2 don't agree!" << endl;
523   }
524 
525   if (count1 != count3 - 2) {
526     passed = false;
527     cerr << "ERROR: Counts do not agree before and after copy!" << endl;
528   }
529 
530   int diff_count = 0;
531   for (int i = 0; i < high_bit_count; i++) {
532     if (bit_array3.GetBit(i) != bit_array4.GetBit(i)) diff_count++;
533   }
534 
535   if (diff_count != 2) {
536     passed = false;
537     cerr << "ERROR in cRawBitArray copy constructor." << endl;
538   }
539 
540 
541   // LOGICAL OPERATORS
542 
543   bit_array4.Resize(1000, 70);
544   int count5 = bit_array4.CountBits(70);
545   bit_array4.NOT(70);
546   int count6 = bit_array4.CountBits(70);
547   bit_array4.NOT(70);
548 
549   if (count5 + count6 != 70) {
550     passed = false;
551     cerr << "ERROR in NOT operation!" << endl;
552   }
553 
554   cRawBitArray bit_array5(70);
555   int pos = 1;
556   int step = 1;
557   while (pos <= 70) {
558     bit_array5.SetBit(70 - pos, true);
559     pos += step++;
560   }
561 
562   cRawBitArray bit_array6(70);
563   bit_array6.AND(bit_array4, bit_array5, 70);
564   int count_and = bit_array6.CountBits(70);
565   if (count_and != 3) {
566     passed = false;
567     cerr << "ERROR in AND operation!" << endl;
568   }
569 
570   bit_array6.OR(bit_array4, bit_array5, 70);
571   int count_or = bit_array6.CountBits(70);
572   if (count_or != 21) {
573     passed = false;
574     cerr << "ERROR in OR operation!" << endl;
575   }
576 
577   bit_array6.NAND(bit_array4, bit_array5, 70);
578   int count_nand = bit_array6.CountBits(70);
579   if (count_nand != 67) {
580     passed = false;
581     cerr << "ERROR in NAND operation!" << endl;
582   }
583 
584   bit_array6.NOR(bit_array4, bit_array5, 70);
585   int count_nor = bit_array6.CountBits(70);
586   if (count_nor != 49) {
587     passed = false;
588     cerr << "ERROR in NOR operation!" << endl;
589   }
590 
591   bit_array6.XOR(bit_array4, bit_array5, 70);
592   int count_xor = bit_array6.CountBits(70);
593   if (count_xor != 18) {
594     passed = false;
595     cerr << "ERROR in XOR operation!" << endl;
596   }
597 
598   bit_array6.EQU(bit_array4, bit_array5, 70);
599   int count_equ = bit_array6.CountBits(70);
600   if (count_equ != 52) {
601     passed = false;
602     cerr << "ERROR in EQU operation!" << endl;
603   }
604 
605   // LEFT AND RIGHT SHIFT
606 
607   cRawBitArray bit_array7(32);
608   bit_array7.SetBit(0, true);
609 
610   bit_array7.SHIFT(32, 0);
611   if (bit_array7.GetBit(0) != true || bit_array7.CountBits(32) != 1) {
612     passed = false;
613     cerr << "ERROR when Shifting by zero bits!" << endl;
614   }
615 
616   bit_array7.SHIFT(32, 31);
617   if (bit_array7.GetBit(31) != true || bit_array7.CountBits(32) != 1) {
618     passed = false;
619     cerr << "ERROR in ShiftLeft!" << endl;
620   }
621 
622   bit_array7.SHIFT(32, -31);
623   if (bit_array7.GetBit(0) != true || bit_array7.CountBits(32) != 1)  {
624     passed = false;
625     cerr << "ERROR in ShiftRight with sign bit!" << endl;
626   }
627 
628   bit_array7.SHIFT(32, 30);
629   bit_array7.SHIFT(32, -30);
630   if (bit_array7.GetBit(0) != true || bit_array7.CountBits(32) != 1) {
631     passed = false;
632     cerr << "ERROR in ShiftRight without sign bit!" << endl;
633   }
634 
635   bit_array7.SHIFT(32, 32);
636   if (bit_array7.CountBits(32) != 0) {
637     passed = false;
638     cerr << "ERROR in ShiftLeft dropping!" << endl;
639   }
640 
641   bit_array7.SetBit(31, true);
642   bit_array7.SHIFT(32, -32);
643   if(bit_array7.CountBits(32) != 0) {
644     passed = false;
645     cerr << "ERROR in ShiftRight dropping!" << endl;
646   }
647 
648   cRawBitArray bit_array8(34);
649   bit_array8.SetBit(0, true);
650 
651   bit_array8.SHIFT(34, 33);
652   if (bit_array8.GetBit(33) != true || bit_array8.CountBits(34) != 1) {
653     passed = false;
654     cerr << "ERROR in ShiftLeft across bit fields!" << endl;
655   }
656 
657   bit_array8.SHIFT(34, -33);
658   if (bit_array8.GetBit(0) != true || bit_array8.CountBits(34) != 1) {
659     passed = false;
660     cerr << "ERROR in ShiftRight accross bit fields!" << endl;
661   }
662 
663   cRawBitArray bit_array9(66);
664   bit_array9.SetBit(0, true);
665   bit_array9.SetBit(32, true);
666 
667   bit_array9.SHIFT(66, 65);
668   if(bit_array9.GetBit(65) != true || bit_array9.CountBits(66) != 1) {
669     passed = false;
670     cerr << "ERROR in ShiftLeft across multiple fields!" << endl;
671   }
672 
673   bit_array9.SHIFT(66, -65);
674   if(bit_array9.GetBit(0) != true || bit_array9.CountBits(66) != 1) {
675     passed = false;
676     cerr << "ERROR in ShiftRight across multiple fields!" << endl;
677   }
678 
679   // INCREMENT
680 
681   cRawBitArray bit_array10(1);
682 
683   bit_array10.INCREMENT(1);
684   if (bit_array10.GetBit(0) != true || bit_array10.CountBits(1) != 1) {
685     passed = false;
686     cerr << "ERROR in INCREMENT operation!" << endl;
687   }
688 
689   bit_array10.INCREMENT(1);
690   if (bit_array10.GetBit(0) != false || bit_array10.CountBits(1) != 0) {
691     passed = false;
692     cerr << "ERROR in INCREMENT overflowing last bit field!" << endl;
693   }
694 
695   cRawBitArray bit_array11(33);
696   for (int i = 0; i < 32; i++) { bit_array11.SetBit(i, true); }
697 
698   bit_array11.INCREMENT(33);
699   if (bit_array11.GetBit(32) != 1 || bit_array11.CountBits(33) != 1) {
700     passed = false;
701     cerr << "ERROR in INCREMENT across fields!" << endl;
702   }
703 
704 //   bit_array4.Print(70);
705 //   bit_array5.Print(70);
706 //   bit_array6.Print(70);
707 //   cout << bit_array6.CountBits(70) << endl;
708 
709   cBitArray ba(74);
710   for (int i = 0; i < 74; i++) {  if (i % 5 == 3) ba[i] = true;  }
711 
712   cBitArray ba2(74);
713   for (int i = 0; i < 74; i++)  {
714     if ((i%2==0 || i%3==0) && i%6 != 0) ba2[i] = true;
715   }
716 
717   if ((ba & ba2).CountBits() != 8) {
718     passed = false;
719     cerr << "ERROR: operator& failed for cBitArray" << endl;
720   }
721 
722   if ((ba | ba2).CountBits() != 43) {
723     passed = false;
724     cerr << "ERROR: operator| failed for cBitArray" << endl;
725   }
726 
727   if ((ba ^ ba2).CountBits() != 35) {
728     passed = false;
729     cerr << "ERROR: operator^ failed for cBitArray" << endl;
730   }
731 
732   if ((~ba).CountBits() != 59) {
733     passed = false;
734     cerr << "ERROR: operator~ failed for cBitArray" << endl;
735   }
736 
737   if ((ba << 65).CountBits() != 2) {
738     passed = false;
739     cerr << "ERROR: operator<< (leftshift) failed for cBitArray" << endl;
740   }
741 
742   if ((ba >> 65).CountBits() != 2) {
743     passed = false;
744     cerr << "ERROR: operator>> (rightshift) failed for cBitArray" << endl;
745   }
746 
747   if ((~ba & ~ba2).CountBits() != 31) {
748     passed = false;
749     cerr << "ERROR: Chained bitwise operators failed for cBitArray" << endl;
750   }
751 
752   if ((++(~ba & ~ba2)).CountBits() != 30) {
753     passed = false;
754     cerr << "ERROR: prefix ++ failed for cBitArray" << endl;
755   }
756 
757   if (((~ba & ~ba2)++).CountBits() != 31) {
758     passed = false;
759     cerr << "ERROR: postfix ++ failed for cBitArray" << endl;
760   }
761 
762   cout << ba << "  " << ba.CountBits() << endl;
763   cout << ba2 << "  " << ba2.CountBits() << endl;
764   cout << (~ba & ~ba2) << "  " << (~ba & ~ba2).CountBits() << endl;
765 
766   if (passed == true) {
767     cout << "cRawBitArray passed Unit Tests." << endl;
768   }
769 }
770 
771 #endif
772