In Java 8
the below code converts integer 3
to bitset and prints {0, 1}
meaning the bit representation of 3
has ones at positions 0
and 1
that is 11
.
System.out.println(BitSet.valueOf(new long[]{3}));
I'm interested in converting a BigInteger
or long
with large value, say 10000000
into the corresponding BitSet
and then back - having the BitSet
object (bit representation) convert it to BigInteger
(long
). I'm also wondering which representation occupies more memory for various values of integer numbers?
As
BigInteger
is big-endian, whileBitSet
is little-endian, the bytes will be reversed when trying to convert directly from one to the other viatoByteArray()
. The simplest solution would be to just reverse them again:By the way, if you are only interested in the bit indices, you may use BigInteger#testBit instead.
You can use the
BigInteger.toByteArray()
andBitSet.toByteArray()
for these:You can use the constructor of the
BigInteger(byte[])
to convert the array of bytes into aBigInteger
and theBitSet.valueOf(byte[])
to convert the data into the desired values.For the given code, it outputs:
Note that the 2-complement notation is used. Thus for negative numbers, it will generate additional ones. And a
2^64-1
will require more than64
bits to represent. This also works with big endian. (see modified answer below).EDIT: there is however one problem with this approach: if there are tailing zeros, these are not taken into account by the program. This can be important because they are part of the representation. You can solve this problem by adding a tailing bit:
And call it with:
About the memory usage
In general both methods will use approximately the same number of bits. For the first implementation (without size marker and thus errors), it is possible that sometimes, the
BitSet
approach will use one byte less than theBigInteger
approach. With the size marker (second approach), it is the opposite: in general theBitSet
will use always one extra byte, except for some rare occasions.