Created
September 7, 2018 02:55
-
-
Save Daomephsta/f4974e07487b075407a0f4dcd30ea8c4 to your computer and use it in GitHub Desktop.
BitEncoderDecoder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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