Hi,
I wrote a simple bits arary library, which can be applied to larger bits sets (any length) or high precision numbers.
import bitarray
when isMainModule:
var
a = newBitsArray(70)
b = newBitsArray(70)
echo " a = ",a
echo " b = ",b
echo "set bits ..."
a.setBits(0,1,2,3,4,69)
b.setBits(6,7,8,9,65)
echo " a = ",a
echo " b = ",b
echo "a & b = ", a & b
echo "a | b = ", a | b
echo "a ^ b = ", a ^ b
echo " ~a = ", ~a
echo "a.shl(1) =",a.shl(1)
echo "a.shl(2) =",a.shl(2)
echo "a.shl(3) =",a.shl(3)
echo "a.shl(69)=",a.shl(69)
echo "a.shr(1) =",a.shr(1)
echo "a.shr(2) =",a.shr(2)
echo "a.shr(3) =",a.shr(3)
echo "a.shr(69)=",a.shr(69)
echo "basic types"
echo (-7).toBitsArray
echo (7).toBitsArray
echo (-1.555).toBitsArray
echo (1.555).toBitsArray
echo (-7.int16).toBitsArray
echo (7.int16).toBitsArray
a = 0000000000000000000000000000000000000000000000000000000000000000000000
b = 0000000000000000000000000000000000000000000000000000000000000000000000
set bits ...
a = 1111100000000000000000000000000000000000000000000000000000000000000001
b = 0000001111000000000000000000000000000000000000000000000000000000010000
a & b = 0000000000000000000000000000000000000000000000000000000000000000000000
a | b = 1111101111000000000000000000000000000000000000000000000000000000010001
a ^ b = 1111101111000000000000000000000000000000000000000000000000000000010001
~a = 0000011111111111111111111111111111111111111111111111111111111111111110
a.shl(1) =1111000000000000000000000000000000000000000000000000000000000000000010
a.shl(2) =1110000000000000000000000000000000000000000000000000000000000000000100
a.shl(3) =1100000000000000000000000000000000000000000000000000000000000000001000
a.shl(69)=1000000000000000000000000000000000000000000000000000000000000000000000
a.shr(1) =0111110000000000000000000000000000000000000000000000000000000000000000
a.shr(2) =0011111000000000000000000000000000000000000000000000000000000000000000
a.shr(3) =0001111100000000000000000000000000000000000000000000000000000000000000
a.shr(69)=0000000000000000000000000000000000000000000000000000000000000000000001
basic types
1001111111111111111111111111111111111111111111111111111111111111
1110000000000000000000000000000000000000000000000000000000000000
1000011101011110001010000111010111100010100001110001111111111101
1000011101011110001010000111010111100010100001110001111111111100
1001111111111111
1110000000000000
You both might be interested in something called "Aggregate Bit Vectors". The idea is simple: for each big 64-bit or whatever word in your bit vector, let that be just 1 bit in a "level higher" structure if any bit is on and zero if they are all off. You can then do the same trick again for a 2nd "index level" or more. What this lets you do is spend a little storage and indirection to iterate over very sparsely populated sets quickly.
This could even be applied to the standard Nim set idea. It maxes out at 65536 bits or 8192 bytes, but with 64 bit ints the first level of index would be only 65536/64=1024 bits=128 bytes = 1..2 cache lines. It's better still to just not iterate, of course..but that is not always possible.