You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ar...@apache.org on 2009/11/13 18:24:28 UTC

svn commit: r835931 - in /incubator/lucene.net/trunk/C#/src: Lucene.Net/SupportClass.cs Lucene.Net/Util/OpenBitSet.cs Lucene.Net/Util/OpenBitSetIterator.cs Test/Util/TestOpenBitSet.cs

Author: aroush
Date: Fri Nov 13 17:24:28 2009
New Revision: 835931

URL: http://svn.apache.org/viewvc?rev=835931&view=rev
Log:
Fixed NUnit test-cases for: TestOpenBitSet

Modified:
    incubator/lucene.net/trunk/C#/src/Lucene.Net/SupportClass.cs
    incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/OpenBitSet.cs
    incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/OpenBitSetIterator.cs
    incubator/lucene.net/trunk/C#/src/Test/Util/TestOpenBitSet.cs

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/SupportClass.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/SupportClass.cs?rev=835931&r1=835930&r2=835931&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/SupportClass.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/SupportClass.cs Fri Nov 13 17:24:28 2009
@@ -622,10 +622,7 @@
         /// <returns>The resulting number from the shift operation</returns>
         public static int URShift(int number, int bits)
         {
-            if (number >= 0)
-                return number >> bits;
-            else
-                return (number >> bits) + (2 << ~bits);
+            return (int) (((uint) number) >> bits);
         }
 
 
@@ -637,10 +634,7 @@
         /// <returns>The resulting number from the shift operation</returns>
         public static long URShift(long number, int bits)
         {
-            if (number >= 0)
-                return number >> bits;
-            else
-                return (number >> bits) + (2 << ~bits);
+            return (long) (((ulong) number) >> bits);
         }
 
 

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/OpenBitSet.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Util/OpenBitSet.cs?rev=835931&r1=835930&r2=835931&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/OpenBitSet.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/OpenBitSet.cs Fri Nov 13 17:24:28 2009
@@ -246,7 +246,7 @@
 		{
 			int i = index >> 6; // div 64
 			int bit = index & 0x3f; // mod 64
-			return ((int) (SupportClass.Number.URShift(bits[i], bit))) & 0x01;
+			return ((int )((ulong) (bits[i]) >> bit)) & 0x01;
 		}
 		
 		
@@ -310,7 +310,7 @@
 			int endWord = ExpandingWordNum(endIndex - 1);
 			
 			long startmask = - 1L << (int) startIndex;
-			long endmask = SupportClass.Number.URShift(- 1L, (int) - endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
+			long endmask = (long) (0xffffffffffffffffUL >> (int) - endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
 			
 			if (startWord == endWord)
 			{
@@ -399,7 +399,7 @@
 			int endWord = ((endIndex - 1) >> 6);
 			
 			long startmask = - 1L << startIndex;
-			long endmask = SupportClass.Number.URShift(- 1L, - endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
+			long endmask = (long) (0xffffffffffffffffUL >> - endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
 			
 			// invert masks since we are clearing
 			startmask = ~ startmask;
@@ -444,7 +444,7 @@
 			int endWord = (int) ((endIndex - 1) >> 6);
 			
 			long startmask = - 1L << (int) startIndex;
-			long endmask = SupportClass.Number.URShift(- 1L, (int) - endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
+			long endmask = (long) (0xffffffffffffffffUL >> (int) - endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
 			
 			// invert masks since we are clearing
 			startmask = ~ startmask;
@@ -575,7 +575,7 @@
 			***/
 			
 			long startmask = - 1L << (int) startIndex;
-			long endmask = SupportClass.Number.URShift(- 1L, (int) - endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
+			long endmask = (long) (0xffffffffffffffffUL >> (int) - endIndex); // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
 			
 			if (startWord == endWord)
 			{
@@ -712,11 +712,11 @@
 		/// </summary>
 		public virtual long NextSetBit(long index)
 		{
-			int i = (int) (SupportClass.Number.URShift(index, 6));
+			int i = (int) (index >> 6);
 			if (i >= wlen)
 				return - 1;
 			int subIndex = (int) index & 0x3f; // index within the word
-			long word = SupportClass.Number.URShift(bits[i], subIndex); // skip all the bits to the right of index
+			long word = (long) ((ulong) bits[i] >> subIndex); // skip all the bits to the right of index
 			
 			if (word != 0)
 			{
@@ -895,7 +895,7 @@
 		/// <summary>returns the number of 64 bit words it would take to hold numBits </summary>
 		public static int Bits2words(long numBits)
 		{
-			return (int) ((SupportClass.Number.URShift((numBits - 1), 6)) + 1);
+			return (int) ((((numBits - 1) >> 6)) + 1);
 		}
 		
 		
@@ -941,7 +941,7 @@
 			for (int i = bits.Length; --i >= 0; )
 			{
 				h ^= bits[i];
-				h = (h << 1) | (SupportClass.Number.URShift(h, 63)); // rotate left
+				h = (h << 1) | ((long) ((ulong) h >> 63)); // rotate left
 			}
 			return (int) ((h >> 32) ^ h); // fold leftmost bits into right
 		}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/OpenBitSetIterator.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Util/OpenBitSetIterator.cs?rev=835931&r1=835930&r2=835931&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/OpenBitSetIterator.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/OpenBitSetIterator.cs Fri Nov 13 17:24:28 2009
@@ -37,8 +37,8 @@
 		// packed inside a 32 bit integer (8 4 bit numbers).  That
 		// should be faster than accessing an array for each index, and
 		// the total array size is kept smaller (256*sizeof(int))=1K
-		protected internal static readonly int[] bitlist = new int[]{0x0, 0x1, 0x2, 0x21, 0x3, 0x31, 0x32, 0x321, 0x4, 0x41, 0x42, 0x421, 0x43, 0x431, 0x432, 0x4321, 0x5, 0x51, 0x52, 0x521, 0x53, 0x531, 0x532, 0x5321, 0x54, 0x541, 0x542, 0x5421, 0x543, 0x5431, 0x5432, 0x54321, 0x6, 0x61, 0x62, 0x621, 0x63, 0x631, 0x632, 0x6321, 0x64, 0x641, 0x642, 0x6421, 0x643, 0x6431, 0x6432, 0x64321, 0x65, 0x651, 0x652, 0x6521, 0x653, 0x6531, 0x6532, 0x65321, 0x654, 0x6541, 0x6542, 0x65421, 0x6543, 0x65431, 0x65432, 0x654321, 0x7, 0x71, 0x72, 0x721, 0x73, 0x731, 0x732, 0x7321, 0x74, 0x741, 0x742, 0x7421, 0x743, 0x7431, 0x7432, 0x74321, 0x75, 0x751, 0x752, 0x7521, 0x753, 0x7531, 0x7532, 0x75321, 0x754, 0x7541, 0x7542, 0x75421, 0x7543, 0x75431, 0x75432, 0x754321, 0x76, 0x761, 0x762, 0x7621, 0x763, 0x7631, 0x7632, 0x76321, 0x764, 0x7641, 0x7642, 0x76421, 0x7643, 0x76431, 0x76432, 0x764321, 0x765, 0x7651, 0x7652, 0x76521, 0x7653, 0x76531, 0x76532, 0x765321, 0x7654, 0x76541, 0x76542, 0x765421, 0x765
 43, 0x765431, 0x765432, 0x7654321, 0x8, 0x81, 0x82, 0x821, 0x83, 0x831, 0x832, 0x8321, 0x84, 0x841, 0x842, 0x8421, 0x843, 0x8431, 0x8432, 0x84321, 0x85, 0x851, 0x852, 0x8521, 0x853, 0x8531, 0x8532, 0x85321, 0x854, 0x8541, 0x8542, 0x85421, 0x8543, 0x85431, 0x85432, 0x854321, 0x86, 0x861, 0x862, 0x8621, 0x863, 0x8631, 0x8632, 0x86321, 0x864, 0x8641, 0x8642, 0x86421, 0x8643, 0x86431, 0x86432, 0x864321, 0x865, 0x8651, 0x8652, 0x86521, 0x8653, 0x86531, 0x86532, 0x865321, 0x8654, 0x86541, 0x86542, 0x865421, 0x86543, 0x865431, 0x865432, 0x8654321, 0x87, 0x871, 0x872, 0x8721, 0x873, 0x8731, 0x8732, 0x87321, 0x874, 0x8741, 0x8742, 0x87421, 0x8743, 0x87431, 0x87432, 0x874321, 0x875, 0x8751, 0x8752, 0x87521, 0x8753, 0x87531, 0x87532, 0x875321, 0x8754, 0x87541, 0x87542, 0x875421, 0x87543, 0x875431, 0x875432, 0x8754321, 0x876, 0x8761, 0x8762, 0x87621, 0x8763, 0x87631, 0x87632, 0x876321, 0x8764, 0x87641, 0x87642, 0x876421, 0x87643, 0x876431, 0x876432, 0x8764321, 0x8765, 0x87651, 0x87652, 
 0x876521, 0x87653, 0x876531, 0x876532, 0x8765321, 0x87654, 
-			0x876541, 0x876542, 0x8765421, 0x876543, 0x8765431, 0x8765432, unchecked((int) 0x87654321)};
+		protected internal static readonly uint[] bitlist = new uint[]{0x0, 0x1, 0x2, 0x21, 0x3, 0x31, 0x32, 0x321, 0x4, 0x41, 0x42, 0x421, 0x43, 0x431, 0x432, 0x4321, 0x5, 0x51, 0x52, 0x521, 0x53, 0x531, 0x532, 0x5321, 0x54, 0x541, 0x542, 0x5421, 0x543, 0x5431, 0x5432, 0x54321, 0x6, 0x61, 0x62, 0x621, 0x63, 0x631, 0x632, 0x6321, 0x64, 0x641, 0x642, 0x6421, 0x643, 0x6431, 0x6432, 0x64321, 0x65, 0x651, 0x652, 0x6521, 0x653, 0x6531, 0x6532, 0x65321, 0x654, 0x6541, 0x6542, 0x65421, 0x6543, 0x65431, 0x65432, 0x654321, 0x7, 0x71, 0x72, 0x721, 0x73, 0x731, 0x732, 0x7321, 0x74, 0x741, 0x742, 0x7421, 0x743, 0x7431, 0x7432, 0x74321, 0x75, 0x751, 0x752, 0x7521, 0x753, 0x7531, 0x7532, 0x75321, 0x754, 0x7541, 0x7542, 0x75421, 0x7543, 0x75431, 0x75432, 0x754321, 0x76, 0x761, 0x762, 0x7621, 0x763, 0x7631, 0x7632, 0x76321, 0x764, 0x7641, 0x7642, 0x76421, 0x7643, 0x76431, 0x76432, 0x764321, 0x765, 0x7651, 0x7652, 0x76521, 0x7653, 0x76531, 0x76532, 0x765321, 0x7654, 0x76541, 0x76542, 0x765421, 0x7
 6543, 0x765431, 0x765432, 0x7654321, 0x8, 0x81, 0x82, 0x821, 0x83, 0x831, 0x832, 0x8321, 0x84, 0x841, 0x842, 0x8421, 0x843, 0x8431, 0x8432, 0x84321, 0x85, 0x851, 0x852, 0x8521, 0x853, 0x8531, 0x8532, 0x85321, 0x854, 0x8541, 0x8542, 0x85421, 0x8543, 0x85431, 0x85432, 0x854321, 0x86, 0x861, 0x862, 0x8621, 0x863, 0x8631, 0x8632, 0x86321, 0x864, 0x8641, 0x8642, 0x86421, 0x8643, 0x86431, 0x86432, 0x864321, 0x865, 0x8651, 0x8652, 0x86521, 0x8653, 0x86531, 0x86532, 0x865321, 0x8654, 0x86541, 0x86542, 0x865421, 0x86543, 0x865431, 0x865432, 0x8654321, 0x87, 0x871, 0x872, 0x8721, 0x873, 0x8731, 0x8732, 0x87321, 0x874, 0x8741, 0x8742, 0x87421, 0x8743, 0x87431, 0x87432, 0x874321, 0x875, 0x8751, 0x8752, 0x87521, 0x8753, 0x87531, 0x87532, 0x875321, 0x8754, 0x87541, 0x87542, 0x875421, 0x87543, 0x875431, 0x875432, 0x8754321, 0x876, 0x8761, 0x8762, 0x87621, 0x8763, 0x87631, 0x87632, 0x876321, 0x8764, 0x87641, 0x87642, 0x876421, 0x87643, 0x876431, 0x876432, 0x8764321, 0x8765, 0x87651, 0x87652
 , 0x876521, 0x87653, 0x876531, 0x876532, 0x8765321, 0x87654, 
+			0x876541, 0x876542, 0x8765421, 0x876543, 0x8765431, 0x8765432, 0x87654321};
 		/// <summary>** the python code that generated bitlist
 		/// def bits2int(val):
 		/// arr=0
@@ -81,17 +81,17 @@
 		{
 			if ((int) word == 0)
 			{
-				wordShift += 32; word = SupportClass.Number.URShift(word, 32);
+				wordShift += 32; word = (long) ((ulong) word >> 32);
 			}
 			if ((word & 0x0000FFFF) == 0)
 			{
-				wordShift += 16; word = SupportClass.Number.URShift(word, 16);
+				wordShift += 16; word = (long) ((ulong) word >> 16);
 			}
 			if ((word & 0x000000FF) == 0)
 			{
-				wordShift += 8; word = SupportClass.Number.URShift(word, 8);
+				wordShift += 8; word = (long) ((ulong) word >> 8);
 			}
-			indexArray = bitlist[(int) word & 0xff];
+			indexArray = (int) bitlist[word & 0xff];
 		}
 		
 		/// <summary>** alternate shift implementations
@@ -129,7 +129,7 @@
 			{
 				if (word != 0)
 				{
-					word = SupportClass.Number.URShift(word, 8);
+					word = (long) ((ulong) word >> 8);
 					wordShift += 8;
 				}
 				
@@ -149,7 +149,7 @@
 			}
 			
 			int bitIndex = (indexArray & 0x0f) + wordShift;
-			indexArray = SupportClass.Number.URShift(indexArray, 4);
+			indexArray = (int) ((uint) indexArray >> 4);
 			// should i<<6 be cached as a separate variable?
 			// it would only save one cycle in the best circumstances.
 			return curDocId = (i << 6) + bitIndex;
@@ -172,7 +172,7 @@
 				return curDocId = NO_MORE_DOCS;
 			}
 			wordShift = target & 0x3f;
-			word = SupportClass.Number.URShift(arr[i], wordShift);
+			word = (long) ((ulong) arr[i] >> wordShift);
 			if (word != 0)
 			{
 				wordShift--; // compensate for 1 based arrIndex
@@ -193,7 +193,7 @@
 			Shift();
 			
 			int bitIndex = (indexArray & 0x0f) + wordShift;
-			indexArray = SupportClass.Number.URShift(indexArray, 4);
+			indexArray = (int) ((uint) indexArray >> 4);
 			// should i<<6 be cached as a separate variable?
 			// it would only save one cycle in the best circumstances.
 			return curDocId = (i << 6) + bitIndex;

Modified: incubator/lucene.net/trunk/C#/src/Test/Util/TestOpenBitSet.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Test/Util/TestOpenBitSet.cs?rev=835931&r1=835930&r2=835931&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Test/Util/TestOpenBitSet.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Test/Util/TestOpenBitSet.cs Fri Nov 13 17:24:28 2009
@@ -98,7 +98,7 @@
 			for (int i = 0; i < iter; i++)
 			{
 				int sz = rand.Next(maxSize);
-				System.Collections.BitArray a = new System.Collections.BitArray((sz % 64 == 0?sz / 64:sz / 64 + 1) * 64);
+				System.Collections.BitArray a = new System.Collections.BitArray(sz);
 				OpenBitSet b = new OpenBitSet(sz);
 				
 				// test the various ways of setting bits
@@ -136,65 +136,174 @@
 				// test that the various ways of accessing the bits are equivalent
 				DoGet(a, b);
 				
-				// test ranges, including possible extension
-				int fromIndex, toIndex;
-				fromIndex = rand.Next(sz + 80);
-				toIndex = fromIndex + rand.Next((sz >> 1) + 1);
-				System.Collections.BitArray aa = (System.Collections.BitArray) a.Clone(); for (int j = fromIndex; j < toIndex; i++) aa.Set(j, !aa.Get(j));
-				OpenBitSet bb = (OpenBitSet) b.Clone(); bb.Flip(fromIndex, toIndex);
-				
-				DoIterate(aa, bb, mode); // a problem here is from flip or doIterate
-				
-				fromIndex = rand.Next(sz + 80);
-				toIndex = fromIndex + rand.Next((sz >> 1) + 1);
-				aa = (System.Collections.BitArray) a.Clone(); for (int j = fromIndex; j < toIndex; j++) aa.Set(j, false);
-				bb = (OpenBitSet) b.Clone(); bb.Clear(fromIndex, toIndex);
-				
-				DoNextSetBit(aa, bb); // a problem here is from clear() or nextSetBit
-				
-				fromIndex = rand.Next(sz + 80);
-				toIndex = fromIndex + rand.Next((sz >> 1) + 1);
-				aa = (System.Collections.BitArray) a.Clone(); for (int j = fromIndex; j < toIndex; j++) aa.Set(j, true);
-				bb = (OpenBitSet) b.Clone(); bb.Set(fromIndex, toIndex);
+                // {{dougsale-2.4.0}}
+                //
+                // Java's java.util.BitSet automatically grows as needed - i.e., when a bit is referenced beyond
+                // the size of the BitSet, an exception isn't thrown - rather, the set grows to the size of the 
+                // referenced bit.
+                //
+                // System.Collections.BitArray does not have this feature, and thus I've faked it here by
+                // "growing" the array explicitly when necessary (creating a new instance of the appropriate size
+                // and setting the appropriate bits).
+                //
+
+                // test ranges, including possible extension
+                int fromIndex, toIndex;
+                fromIndex = rand.Next(sz + 80);
+                toIndex = fromIndex + rand.Next((sz >> 1) + 1);
+
+                // {{dougsale-2.4.0}}:
+                // The following commented-out, compound statement's 'for loop' implicitly grows the Java BitSets 'a'
+                // and 'aa' to the same cardinality as 'j+1' when 'a.Count < j+1' and 'fromIndex < toIndex':
+                //BitArray aa = (BitArray)a.Clone(); for (int j = fromIndex; j < toIndex; j++) aa.Set(j, !a.Get(j));
+                // So, if necessary, lets explicitly grow 'a' now; then 'a' and its clone, 'aa', will be of the required size.
+                if (a.Count < toIndex && fromIndex < toIndex)
+                {
+                    System.Collections.BitArray tmp = new System.Collections.BitArray(toIndex, false);
+                    for (int k = 0; k < a.Count; k++)
+                        tmp.Set(k, a.Get(k));
+                    a = tmp;
+                }
+                // {{dougsale-2.4.0}}: now we can invoke this statement without going 'out-of-bounds'
+                System.Collections.BitArray aa = (System.Collections.BitArray)a.Clone(); for (int j = fromIndex; j < toIndex; j++) aa.Set(j, !a.Get(j));
+                OpenBitSet bb = (OpenBitSet)b.Clone(); bb.Flip(fromIndex, toIndex);
+
+                DoIterate(aa, bb, mode); // a problem here is from flip or doIterate
+
+                fromIndex = rand.Next(sz + 80);
+                toIndex = fromIndex + rand.Next((sz >> 1) + 1);
+                // {{dougsale-2.4.0}}:
+                // The following commented-out, compound statement's 'for loop' implicitly grows the Java BitSet 'aa'
+                // when 'a.Count < j+1' and 'fromIndex < toIndex'
+                //aa = (BitArray)a.Clone(); for (int j = fromIndex; j < toIndex; j++) aa.Set(j, false);
+                // So, if necessary, lets explicitly grow 'aa' now
+                if (a.Count < toIndex && fromIndex < toIndex)
+                {
+                    aa = new System.Collections.BitArray(toIndex);
+                    for (int k = 0; k < a.Count; k++)
+                        aa.Set(k, a.Get(k));
+                }
+                else
+                {
+                    aa = (System.Collections.BitArray)a.Clone();
+                }
+                for (int j = fromIndex; j < toIndex; j++) aa.Set(j, false);
+                bb = (OpenBitSet)b.Clone(); bb.Clear(fromIndex, toIndex);
+
+                DoNextSetBit(aa, bb); // a problem here is from clear() or nextSetBit
+
+                fromIndex = rand.Next(sz + 80);
+                toIndex = fromIndex + rand.Next((sz >> 1) + 1);
+                // {{dougsale-2.4.0}}:
+                // The following commented-out, compound statement's 'for loop' implicitly grows the Java BitSet 'aa'
+                // when 'a.Count < j+1' and 'fromIndex < toIndex'
+                //aa = (BitArray)a.Clone(); for (int j = fromIndex; j < toIndex; j++) aa.Set(j, false);
+                // So, if necessary, lets explicitly grow 'aa' now
+                if (a.Count < toIndex && fromIndex < toIndex)
+                {
+                    aa = new System.Collections.BitArray(toIndex);
+                    for (int k = 0; k < a.Count; k++)
+                        aa.Set(k, a.Get(k));
+                }
+                else
+                {
+                    aa = (System.Collections.BitArray)a.Clone();
+                }
+                for (int j = fromIndex; j < toIndex; j++) aa.Set(j, true);
+                bb = (OpenBitSet)b.Clone(); bb.Set(fromIndex, toIndex);
 				
 				DoNextSetBit(aa, bb); // a problem here is from set() or nextSetBit     
 				
 				
 				if (a0 != null)
 				{
-					Assert.AreEqual(a.Equals(a0), b.Equals(b0));
-					
-					Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a), b.Cardinality());
-					
-					System.Collections.BitArray a_and = (System.Collections.BitArray) a.Clone();
-					a_and.And(a0);
-					System.Collections.BitArray a_or = (System.Collections.BitArray) a.Clone();
-					a_or.Or(a0);
-					System.Collections.BitArray a_xor = (System.Collections.BitArray) a.Clone();
-					a_xor.Xor(a0);
-					System.Collections.BitArray a_andn = (System.Collections.BitArray) a.Clone(); a_andn.And(a0.Not());
-					
-					OpenBitSet b_and = (OpenBitSet) b.Clone(); Assert.AreEqual(b, b_and); b_and.And(b0);
-					OpenBitSet b_or = (OpenBitSet) b.Clone(); b_or.Or(b0);
-					OpenBitSet b_xor = (OpenBitSet) b.Clone(); b_xor.Xor(b0);
-					OpenBitSet b_andn = (OpenBitSet) b.Clone(); b_andn.AndNot(b0);
-					
-					DoIterate(a_and, b_and, mode);
-					DoIterate(a_or, b_or, mode);
-					DoIterate(a_xor, b_xor, mode);
-					DoIterate(a_andn, b_andn, mode);
-					
-					Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a_and), b_and.Cardinality());
-					Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a_or), b_or.Cardinality());
-					Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a_xor), b_xor.Cardinality());
-					Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a_andn), b_andn.Cardinality());
-					
-					// test non-mutating popcounts
-					Assert.AreEqual(b_and.Cardinality(), OpenBitSet.IntersectionCount(b, b0));
-					Assert.AreEqual(b_or.Cardinality(), OpenBitSet.UnionCount(b, b0));
-					Assert.AreEqual(b_xor.Cardinality(), OpenBitSet.XorCount(b, b0));
-					Assert.AreEqual(b_andn.Cardinality(), OpenBitSet.AndNotCount(b, b0));
-				}
+                    Assert.AreEqual(a.Equals(a0), b.Equals(b0));
+
+                    Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a), b.Cardinality());
+
+                    // {{dougsale-2.4.0}}
+                    //
+                    // The Java code used java.util.BitSet, which grows as needed.
+                    // When a bit, outside the dimension of the set is referenced,
+                    // the set automatically grows to the necessary size.  The
+                    // new entries default to false.
+                    //
+                    // BitArray does not grow automatically and is not growable.
+                    // Thus when BitArray instances of mismatched cardinality
+                    // interact, we must first explicitly "grow" the smaller one.
+                    //
+                    // This growth is acheived by creating a new instance of the
+                    // required size and copying the appropriate values.
+                    //
+
+                    //BitArray a_and = (BitArray)a.Clone(); a_and.And(a0);
+                    //BitArray a_or = (BitArray)a.Clone(); a_or.Or(a0);
+                    //BitArray a_xor = (BitArray)a.Clone(); a_xor.Xor(a0);
+                    //BitArray a_andn = (BitArray)a.Clone(); for (int j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
+
+                    System.Collections.BitArray a_and;
+                    System.Collections.BitArray a_or;
+                    System.Collections.BitArray a_xor;
+                    System.Collections.BitArray a_andn;
+
+                    if (a.Count < a0.Count)
+                    {
+                        // the Java code would have implicitly resized 'a_and', 'a_or', 'a_xor', and 'a_andn'
+                        // in this case, so we explicitly create a resized stand-in for 'a' here, allowing for
+                        // a to keep its original size while 'a_and', 'a_or', 'a_xor', and 'a_andn' are resized
+                        System.Collections.BitArray tmp = new System.Collections.BitArray(a0.Count, false);
+                        for (int z = 0; z < a.Count; z++)
+                            tmp.Set(z, a.Get(z));
+
+                        a_and = (System.Collections.BitArray)tmp.Clone(); a_and.And(a0);
+                        a_or = (System.Collections.BitArray)tmp.Clone(); a_or.Or(a0);
+                        a_xor = (System.Collections.BitArray)tmp.Clone(); a_xor.Xor(a0);
+                        a_andn = (System.Collections.BitArray)tmp.Clone(); for (int j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
+                    }
+                    else if (a.Count > a0.Count)
+                    {
+                        // the Java code would have implicitly resized 'a0' in this case, so
+                        // we explicitly do so here:
+                        System.Collections.BitArray tmp = new System.Collections.BitArray(a.Count, false);
+                        for (int z = 0; z < a0.Count; z++)
+                            tmp.Set(z, a0.Get(z));
+                        a0 = tmp;
+
+                        a_and = (System.Collections.BitArray)a.Clone(); a_and.And(a0);
+                        a_or = (System.Collections.BitArray)a.Clone(); a_or.Or(a0);
+                        a_xor = (System.Collections.BitArray)a.Clone(); a_xor.Xor(a0);
+                        a_andn = (System.Collections.BitArray)a.Clone(); for (int j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
+                    }
+                    else
+                    {
+                        // 'a' and 'a0' are the same size, no explicit growing necessary
+                        a_and = (System.Collections.BitArray)a.Clone(); a_and.And(a0);
+                        a_or = (System.Collections.BitArray)a.Clone(); a_or.Or(a0);
+                        a_xor = (System.Collections.BitArray)a.Clone(); a_xor.Xor(a0);
+                        a_andn = (System.Collections.BitArray)a.Clone(); for (int j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
+                    }
+
+                    OpenBitSet b_and = (OpenBitSet)b.Clone(); Assert.AreEqual(b, b_and); b_and.And(b0);
+                    OpenBitSet b_or = (OpenBitSet)b.Clone(); b_or.Or(b0);
+                    OpenBitSet b_xor = (OpenBitSet)b.Clone(); b_xor.Xor(b0);
+                    OpenBitSet b_andn = (OpenBitSet)b.Clone(); b_andn.AndNot(b0);
+
+                    DoIterate(a_and, b_and, mode);
+                    DoIterate(a_or, b_or, mode);
+                    DoIterate(a_xor, b_xor, mode);
+                    DoIterate(a_andn, b_andn, mode);
+
+                    Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a_and), b_and.Cardinality());
+                    Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a_or), b_or.Cardinality());
+                    Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a_xor), b_xor.Cardinality());
+                    Assert.AreEqual(SupportClass.BitSetSupport.Cardinality(a_andn), b_andn.Cardinality());
+
+                    // test non-mutating popcounts
+                    Assert.AreEqual(b_and.Cardinality(), OpenBitSet.IntersectionCount(b, b0));
+                    Assert.AreEqual(b_or.Cardinality(), OpenBitSet.UnionCount(b, b0));
+                    Assert.AreEqual(b_xor.Cardinality(), OpenBitSet.XorCount(b, b0));
+                    Assert.AreEqual(b_andn.Cardinality(), OpenBitSet.AndNotCount(b, b0));
+                }
 				
 				a0 = a;
 				b0 = b;