Skip to content

Instantly share code, notes, and snippets.

@Daomephsta
Created September 7, 2018 02:55
Show Gist options
  • Save Daomephsta/f4974e07487b075407a0f4dcd30ea8c4 to your computer and use it in GitHub Desktop.
Save Daomephsta/f4974e07487b075407a0f4dcd30ea8c4 to your computer and use it in GitHub Desktop.
BitEncoderDecoder
package daomephsta.umbra.bitmanipulation;
import java.util.BitSet;
import java.util.stream.IntStream;
import com.google.common.math.IntMath;
class BitEncoderDecoderFixedBitCount implements IBitEncoderDecoder
{
private final BitSet bits;
private final int bitCount;
public BitEncoderDecoderFixedBitCount(int bitCount)
{
this.bitCount = bitCount;
this.bits = new BitSet(bitCount);
}
@Override
public void encode(int value)
{
encode(0, bitCount, value);
}
@Override
public void encode(int fromIndex, int toIndex, int value)
{
int maxStorableValue = IntMath.pow(2, toIndex - fromIndex) - 1;
if (value > maxStorableValue)
{
throw new IllegalArgumentException(String.format(
"%d is larger than %d, the largest integer that can be stored in %d bits",
value, maxStorableValue, toIndex - fromIndex));
}
int quotient = value;
int bitIndex = toIndex - 1;
while (quotient != 0)
{
bits.set(bitIndex--, quotient % 2 == 1);
// This is supposed to be integer division
quotient = quotient / 2;
}
}
@Override
public int decode()
{
return decode(0, bitCount);
}
@Override
public int decode(int fromIndex, int toIndex)
{
int result = 0;
for(int i = 0; i < size(); i++)
{
if (bits.get(i))
result += IntMath.pow(2, size() - i - 1);
}
System.out.println(result);
return result >> fromIndex;
}
@Override
public byte[] toByteArray()
{
return bits.toByteArray();
}
@Override
public long[] toLongArray()
{
return bits.toLongArray();
}
@Override
public void flip(int bitIndex)
{
bits.flip(bitIndex);
}
@Override
public void flip(int fromIndex, int toIndex)
{
bits.flip(fromIndex, toIndex);
}
@Override
public void set(int bitIndex)
{
bits.set(bitIndex);
}
@Override
public void set(int bitIndex, boolean value)
{
bits.set(bitIndex, value);
}
@Override
public void set(int fromIndex, int toIndex)
{
bits.set(fromIndex, toIndex);
}
@Override
public void set(int fromIndex, int toIndex, boolean value)
{
bits.set(fromIndex, toIndex, value);
}
@Override
public void clear(int bitIndex)
{
bits.clear(bitIndex);
}
@Override
public void clear(int fromIndex, int toIndex)
{
bits.clear(fromIndex, toIndex);
}
@Override
public void clear()
{
bits.clear();
}
@Override
public boolean get(int bitIndex)
{
return bits.get(bitIndex);
}
@Override
public boolean isEmpty()
{
return bits.isEmpty();
}
@Override
public int cardinality()
{
return bits.cardinality();
}
@Override
public int hashCode()
{
return bits.hashCode();
}
@Override
public int size()
{
return bitCount;
}
@Override
public boolean equals(Object obj)
{
return bits.equals(obj);
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < size(); i++)
{
sb.append(get(i) ? 1 : 0);
}
return sb.toString();
}
@Override
public IntStream stream()
{
throw new UnsupportedOperationException("Not implemented yet");
}
}
package daomephsta.umbra.test.bitshifting;
import static org.junit.Assert.*;
import java.util.stream.IntStream;
import org.junit.Test;
import daomephsta.umbra.bitmanipulation.IBitEncoderDecoder;
public class BitEncoderDecoderFixedBitCountTest
{
@Test
public void testDecode()
{
IBitEncoderDecoder bitEncoderDecoder = IBitEncoderDecoder.fixedBitCount(4);
bitEncoderDecoder.set(0);
bitEncoderDecoder.set(1);
System.out.println(bitEncoderDecoder);
assertEquals("decode() failed to correctly decode a manually encoded & shifted integer", 3, bitEncoderDecoder.decode(0, 2));
}
@Test
public void testEncode()
{
IBitEncoderDecoder bitEncoderDecoder = IBitEncoderDecoder.fixedBitCount(4);
bitEncoderDecoder.encode(0, 2, 3);
assertTrue("encode() failed to correctly shift & encode an integer",
bitEncoderDecoder.get(0) && bitEncoderDecoder.get(1) && !bitEncoderDecoder.get(2) && !bitEncoderDecoder.get(3));
}
@Test
public void testEncodeDecode()
{
IBitEncoderDecoder bitEncoderDecoder = IBitEncoderDecoder.fixedBitCount(4);
int[] testInts = IntStream.range(0, 16).toArray();
for (int testInt : testInts)
{
bitEncoderDecoder.encode(testInt);
assertEquals(String.format("%1$s#encode() & %1$s#encode() do not map 1:1 for value %2$s.",
bitEncoderDecoder.getClass().getSimpleName(), testInt), bitEncoderDecoder.decode(), testInt);
}
bitEncoderDecoder.clear();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment