What are the options to quickly list the 1's of a Java BigInteger? We can assume the BigInteger is positive, but it might be a rather large Java BigInteger with sparely distributed 1's. Nevertheless we would like to find them quickly. I would like to have an enumerator or iterator for the bit-positions of the 1's of a Java BigInteger.
Asked
Active
Viewed 83 times
0
-
Chai T. Rex's answer does what you want, but I am not sure if it is faster than simply testing each bit with `testBit()` in a loop (Henry's comment). You could test both and see which is faster or at least fast enough. If the 1 bits are pretty sparse, the `getLowestSetBit()` -- `clearBit()` method could be faster. – Rudy Velthuis Feb 04 '18 at 11:35
3 Answers
1
You can use BigInteger
's getLowestSetBit
and clearBit
methods. For example, to print them out:
public static final void printOneIndexes(BigInteger n) {
while (!n.equals(BigInteger.ZERO)) {
int i = n.getLowestSetBit();
System.out.printf(" %d", i);
n = n.clearBit(i);
}
}

Chai T. Rex
- 2,972
- 1
- 15
- 33
0
Use .toString(radix) method. Like this: bigInteger.toString(2) and then check for ones in a string

Robert K.
- 1,043
- 1
- 8
- 20
-
2Why would you convert to a string, when you can test the bits directly `BigInteger.testBit(int n)`? – Henry Feb 03 '18 at 09:50
-
@Ridcully the result would be the same as `bigInteger.bitCount()` which might be even easier to read and understand. – Henry Feb 03 '18 at 12:22
-
@Ridcully because this is not the question. OP wants the bit positions, not the number of them. – Henry Feb 03 '18 at 18:16
0
One can use getLowestSetBit()
, but tests showed that the following is about 3-4 times as fast:
public static final void printOneIndexes(BigInteger n)
{
for (int i = 0; i < n.bitLength(); i++)
{
if (n.testBit(i))
System.out.printf(" %d", i);
}
}
Of course, if you remove the printing, and store the results in a list, it can be much faster still.
I tested it with a BigInteger with only a few bits set, created by:
public static BigInteger makeSparseInt()
{
BigInteger b = BigInteger.ZERO.setBit(1000000);
Random r = new Random();
for (int i = 0; i < 100; i++)
{
b = b.setBit(r.nextInt(1000000));
}
return b;
}

Rudy Velthuis
- 28,387
- 5
- 46
- 94