BitSet to and from integer/long - java

If I have an integer that I'd like to perform bit manipulation on, how can I load it into a java.util.BitSet? How can I convert it back to an int or long? I'm not so concerned about the size of the BitSet -- it will always be 32 or 64 bits long. I'd just like to use the set(), clear(), nextSetBit(), and nextClearBit() methods rather than bitwise operators, but I can't find an easy way to initialize a bit set with a numeric type.

The following code creates a bit set from a long value and vice versa:
public class Bits {
public static BitSet convert(long value) {
BitSet bits = new BitSet();
int index = 0;
while (value != 0L) {
if (value % 2L != 0) {
bits.set(index);
}
++index;
value = value >>> 1;
}
return bits;
}
public static long convert(BitSet bits) {
long value = 0L;
for (int i = 0; i < bits.length(); ++i) {
value += bits.get(i) ? (1L << i) : 0L;
}
return value;
}
}
EDITED: Now both directions, #leftbrain: of cause, you are right

Add to finnw answer: there are also BitSet.valueOf(long[]) and BitSet.toLongArray(). So:
int n = 12345;
BitSet bs = BitSet.valueOf(new long[]{n});
long l = bs.toLongArray()[0];

Java 7 has BitSet.valueOf(byte[]) and BitSet.toByteArray()
If you are stuck with Java 6 or earlier, you can use BigInteger if it is not likely to be a performance bottleneck - it has getLowestSetBit, setBit and clearBit methods (the last two will create a new BigInteger instead of modifying in-place.)

To get a long back from a small BitSet in a 'streamy' way:
long l = bitSet.stream()
.takeWhile(i -> i < Long.SIZE)
.mapToLong(i -> 1L << i)
.reduce(0, (a, b) -> a | b);
Vice-versa:
BitSet bitSet = IntStream.range(0, Long.SIZE - 1)
.filter(i -> 0 != (l & 1L << i))
.collect(BitSet::new, BitSet::set, BitSet::or);
N.B.: Using BitSet::valueOf and BitSet::toLongArray is of course easier.

Pretty much straight from the documentation of nextSetBit
value=0;
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
value += (1 << i)
}

Isn't the public void set(int bit) method what your looking for?

Related

How can I create a stream of bits from a byte array? [duplicate]

How can i iterate bits in a byte array?
You'd have to write your own implementation of Iterable<Boolean> which took an array of bytes, and then created Iterator<Boolean> values which remembered the current index into the byte array and the current index within the current byte. Then a utility method like this would come in handy:
private static Boolean isBitSet(byte b, int bit)
{
return (b & (1 << bit)) != 0;
}
(where bit ranges from 0 to 7). Each time next() was called you'd have to increment your bit index within the current byte, and increment the byte index within byte array if you reached "the 9th bit".
It's not really hard - but a bit of a pain. Let me know if you'd like a sample implementation...
public class ByteArrayBitIterable implements Iterable<Boolean> {
private final byte[] array;
public ByteArrayBitIterable(byte[] array) {
this.array = array;
}
public Iterator<Boolean> iterator() {
return new Iterator<Boolean>() {
private int bitIndex = 0;
private int arrayIndex = 0;
public boolean hasNext() {
return (arrayIndex < array.length) && (bitIndex < 8);
}
public Boolean next() {
Boolean val = (array[arrayIndex] >> (7 - bitIndex) & 1) == 1;
bitIndex++;
if (bitIndex == 8) {
bitIndex = 0;
arrayIndex++;
}
return val;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static void main(String[] a) {
ByteArrayBitIterable test = new ByteArrayBitIterable(
new byte[]{(byte)0xAA, (byte)0xAA});
for (boolean b : test)
System.out.println(b);
}
}
Original:
for (int i = 0; i < byteArray.Length; i++)
{
byte b = byteArray[i];
byte mask = 0x01;
for (int j = 0; j < 8; j++)
{
bool value = b & mask;
mask << 1;
}
}
Or using Java idioms
for (byte b : byteArray ) {
for ( int mask = 0x01; mask != 0x100; mask <<= 1 ) {
boolean value = ( b & mask ) != 0;
}
}
An alternative would be to use a BitInputStream like the one you can find here and write code like this:
BitInputStream bin = new BitInputStream(new ByteArrayInputStream(bytes));
while(true){
int bit = bin.readBit();
// do something
}
bin.close();
(Note: Code doesn't contain EOFException or IOException handling for brevity.)
But I'd go with Jon Skeets variant and do it on my own.
I needed some bit streaming in my application. Here you can find my BitArray implementation. It is not a real iterator pattern but you can ask for 1-32 bits from the array in a streaming way. There is also an alternate implementation called BitReader later in the file.
I know, probably not the "coolest" way to do it, but you can extract each bit with the following code.
int n = 156;
String bin = Integer.toBinaryString(n);
System.out.println(bin);
char arr[] = bin.toCharArray();
for(int i = 0; i < arr.length; ++i) {
System.out.println("Bit number " + (i + 1) + " = " + arr[i]);
}
10011100
Bit number 1 = 1
Bit number 2 = 0
Bit number 3 = 0
Bit number 4 = 1
Bit number 5 = 1
Bit number 6 = 1
Bit number 7 = 0
Bit number 8 = 0
You can iterate through the byte array, and for each byte use the bitwise operators to iterate though its bits.
Alternatively, you can use BitSet for this:
byte[] bytes=...;
BitSet bitSet=BitSet.valueOf(bytes);
for(int i=0;i<bitSet.length();i++){
boolean bit=bitSet.get(i);
//use your bit
}

How to manipulate the bits in a long?

I want to transform a long to binary code, then change some bits and get the long again. I have found this post Java long to binary but I still can't achieve what I want.
I think there is two ways to achieve my goal:
Going from long to bitset and to long again
Going from long to binary String and then to int array and then to long again
public static long changeHalf(long x){
int[] firstHalf = new int[32];
int[] secondHalf = new int[32];
int[] result = new int[64];
String binaryOfLong = Long.toBinaryString(x);
for (int i = 0; i < firstHalf.length; i++) {
}
for (int i = 0; i < secondHalf.length; i++) {
result[i] = secondHalf[i];
}
for (int i = 0; i < firstHalf.length; i++) {
result[i+32] = firstHalf[i];
}
String s = Arrays.toString(result);
return Long.parseLong(s);
}
Rather than converting a long to arrays of int, just use bitwise operations.
I want to swap the first 32 bits with the last 32 bits
That would be:
long result = ((x & 0xFFFFFFFF00000000l) >> 32) | ((x & 0x00000000FFFFFFFFl) << 32);
That masks off the first 32 bits, shifts them to the right, masks off the last 32 bits, shifts them to the left, and combines the result with | (OR).
Live example:
class Example
{
public static void main (String[] args) throws java.lang.Exception
{
long x = 0x1000000020000000l;
long result = ((x & 0xFFFFFFFF00000000l) >> 32) | ((x & 0x00000000FFFFFFFFl) << 32);
System.out.printf("0x%016X\n", x);
System.out.printf("0x%016X\n", result);
}
}
Outputs:
0x1000000020000000
0x2000000010000000
More in the Bitwise and Bit Shift Operators tutorial.

java - how to create and manipulate a bit array with length of 10 million bits

I just came across a problem; it was easy to solve in pseudo code, but when I started coding it in java; I started to realize I didn't know where to start...
Here is what I need to do:
I need a bit array of size 10 million (bits) (let's call it A).
I need to be able to set the elements in this array to 1 or 0 (A[99000]=1).
I need to iterate through the 10 million elements.
The "proper" way in Java is to use the already-existing BitSet class pointed out by Hunter McMillen. If you're figuring out how a large bit-array is managed purely for the purpose of thinking through an interesting problem, then calculating the position of a bit in an array of bytes is just basic modular arithmetic.
public class BitArray {
private static final int ALL_ONES = 0xFFFFFFFF;
private static final int WORD_SIZE = 32;
private int bits[] = null;
public BitArray(int size) {
bits = new int[size / WORD_SIZE + (size % WORD_SIZE == 0 ? 0 : 1)];
}
public boolean getBit(int pos) {
return (bits[pos / WORD_SIZE] & (1 << (pos % WORD_SIZE))) != 0;
}
public void setBit(int pos, boolean b) {
int word = bits[pos / WORD_SIZE];
int posBit = 1 << (pos % WORD_SIZE);
if (b) {
word |= posBit;
} else {
word &= (ALL_ONES - posBit);
}
bits[pos / WORD_SIZE] = word;
}
}
Use BitSet (as Hunter McMillen already pointed out in a comment). You can easily get and set bits. To iterate just use a normal for loop.
Here is a more optimized implementation of phatfingers 'BitArray'
class BitArray {
private static final int MASK = 63;
private final long len;
private long bits[] = null;
public BitArray(long size) {
if ((((size-1)>>6) + 1) > 2147483647) {
throw new IllegalArgumentException(
"Field size to large, max size = 137438953408");
}else if (size < 1) {
throw new IllegalArgumentException(
"Field size to small, min size = 1");
}
len = size;
bits = new long[(int) (((size-1)>>6) + 1)];
}
public boolean getBit(long pos) {
return (bits[(int)(pos>>6)] & (1L << (pos&MASK))) != 0;
}
public void setBit(long pos, boolean b) {
if (getBit(pos) != b) { bits[(int)(pos>>6)] ^= (1L << (pos&MASK)); }
}
public long getLength() {
return len;
}
}
Since we use fields of 64 we extend the maximum size to 137438953408-bits which is roughly what fits in 16GB of ram. Additionally we use masks and bit shifts instead of division and modulo operations the reducing the computation time. The improvement is quite substantial.
byte[] A = new byte[10000000];
A[99000] = 1;
for(int i = 0; i < A.length; i++) {
//do something
}
If you really want bits, you can use boolean and let true = 1, and false = 0.
boolean[] A = new boolean[10000000];
//etc

AtomicBitSet implementation for java

The standard api does not include an AtomicBitSet implementation. I could roll my own on top of AtomicIntegerArray, but would prefer not too.
Is anyone aware of an existing implementation released under a licence compatible with Apache 2? I require only basic operations to set and check bits.
Edit:
The code is both performance and memory critical so I'd like to avoid synchronization or an integer per flag if possible.
I would use an AtomicIntegerArray and I would use 32 flags per integer which would give you the same density as BitSet but without needing locks for thread safety.
public class AtomicBitSet {
private final AtomicIntegerArray array;
public AtomicBitSet(int length) {
int intLength = (length + 31) >>> 5; // unsigned / 32
array = new AtomicIntegerArray(intLength);
}
public void set(long n) {
int bit = 1 << n;
int idx = (int) (n >>> 5);
while (true) {
int num = array.get(idx);
int num2 = num | bit;
if (num == num2 || array.compareAndSet(idx, num, num2))
return;
}
}
public boolean get(long n) {
int bit = 1 << n;
int idx = (int) (n >>> 5);
int num = array.get(idx);
return (num & bit) != 0;
}
}
Look at http://www.javamex.com/tutorials/synchronization_concurrency_7_atomic_integer_long.shtml
Not exactly using BitSet, but AtomicInteger.

Convert bit vector (array of booleans) to an integer, and integer to bit vector, in Java

What's the best way to unstub the following functions?
// Convert a bit-vector to an integer.
int bitvec2int(boolean[] b)
{
[CODE HERE]
}
// Convert an integer x to an n-element bit-vector.
boolean[] int2bitvec(int x, int n)
{
[CODE HERE]
}
Or is there a better way to do that sort of thing than passing boolean arrays around?
This comes up in an Android app where we need an array of 20 booleans to persist and the easiest way to do that is to write an integer or string to the key-value store.
I'll post the way we (Bee and I) wrote the above as an answer. Thanks!
Use java.util.BitSet instead. It'd be much faster than dealing with boolean[].
Also, you should really ask yourself if these 20 boolean really should be enum, in which case you can use EnumSet, which is the Java solution to the bit fields technique from C (see: Effective Java 2nd Edition: Use EnumSet instead of bit fields).
BitSet to/from int conversion
You might as well just use BitSet and drop the int, but just in case you need these:
static BitSet toBitSet(int i) {
BitSet bs = new BitSet(Integer.SIZE);
for (int k = 0; k < Integer.SIZE; k++) {
if ((i & (1 << k)) != 0) {
bs.set(k);
}
}
return bs;
}
static int toInt(BitSet bs) {
int i = 0;
for (int pos = -1; (pos = bs.nextSetBit(pos+1)) != -1; ) {
i |= (1 << pos);
}
return i;
}
Two different techniques were deliberately used for instructional purposes. For robustness, the BitSet to int conversion should ensure that 32 bits is enough.
EnumSet example
This example is based on the one given in the book:
import java.util.*;
public enum Style {
BOLD, ITALIC, UNDERLINE, STRIKETHROUGH;
public static void main(String[] args) {
Set<Style> s1 = EnumSet.of(BOLD, UNDERLINE);
System.out.println(s1); // prints "[BOLD, UNDERLINE]"
s1.addAll(EnumSet.of(ITALIC, UNDERLINE));
System.out.println(s1.contains(ITALIC)); // prints "true"
}
}
From the API:
This representation is extremely compact and efficient. The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based "bit flags."
// Convert a big-endian bit-vector to an integer.
int bitvec2int(boolean[] b)
{
int x = 0;
for(boolean i : b) x = x << 1 | (i?1:0);
return x;
}
// Convert an integer x to an n-element big-endian bit-vector.
boolean[] int2bitvec(int x, int n)
{
boolean[] b = new boolean[n];
for(int i = 0; i < n; i++) b[i] = (1 << n-i-1 & x) != 0;
return b;
}

Categories

Resources