I'm trying to do a memory writing program with bits as part of a CPU simulating program and I don't understand something. I'm making a function to write int value into the memory which is byte double array broken down into segments. Now, I don't understand why the following writeWord function is not working probably, I'll post relevant code as well as the function.
public class RealMemory implements Memory {
public static final int BYTES_PER_INT = 4;
public static final int BITS_PER_BYTE = 8;
private final int segmentSize;
private final int numberOfSegments;
private byte[][] memory;
public RealMemory (int segmentSize, int numberOfSegments) {
this.segmentSize = segmentSize;
this.numberOfSegments = numberOfSegments;
this.memory = new byte[this.numberOfSegments][this.segmentSize];
}
private byte[] getSegment(int segment) {
assert(segment >= 0 && segment < numberOfSegments);
return memory[segment];
}
public void writeWord (int segment, int offset, int value) {
assert (offset >= 0 && offset < segmentSize - BYTES_PER_INT
&& offset % BYTES_PER_INT == 0);
byte[] byteword = new byte[BYTES_PER_INT];
int mask = 1;
for (int i=offset; i < offset + BYTES_PER_INT; i++) {
byteword[i-offset] = (byte) (value & mask);
mask <<= 1;
getSegment(segment)[i]=byteword[i-offset];
}
}
}
I know the way I try to breakdown the value into bits is wrong, I just don't understand bitwise operation needed here fully is my guess. Any help?
Your problem is mask = 1. You don't read bytes, but single bits instead.
To read bytes, use int mask = (1 << BITS_PER_BYTE) - 1; and mask <<= BITS_PER_BYTE;. Once you masked out the relevant parts you also have to shift it to the right. As Stanislav Bashkyrtsev suggested, this can be done directly on the value instead of shifting the mask.
int mask = (1 << BITS_PER_BYTE) - 1;
for (int i=offset; i < offset + BYTES_PER_INT; i++) {
byteword[i-offset] = (byte) (value & mask);
value >>= BITS_PER_BYTE;
getSegment(segment)[i]=byteword[i-offset];
}
Related
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
}
So in the program I need to read an number from the user which needs to be changed from little endian encoding to whatever encoding the user wants to change it to. The encoding entered by the user is just a 4 digits number which just means which byte should be where after the encoding. e.g. 4321 means put the 4th byte first followed by the 3rd and so on. the encoding can take other form such as 3214 etc.
This is my code, would really appreciate if someone point out where I am missing out.
import java.util.Scanner;
class encoding {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String byteOrder = sc.next();
long[] bitMask = { // little endian
Long.parseLong("11111111000000000000000000000000", 2),
Long.parseLong("00000000111111110000000000000000", 2),
Long.parseLong("00000000000000001111111100000000", 2),
Long.parseLong("00000000000000000000000011111111", 2)
};
int[] bytes = {
(int)(bitMask[0] & n),
(int)(bitMask[1] & n),
(int)(bitMask[2] & n),
(int)(bitMask[3] & n)
};
int result = 0;
shuffleBytes(bytes, byteOrder);
for (int i = 0; i < 4; i++) {
bytes[i] = bytes[i] << (i * 8);
result |= bytes[i];
}
System.out.println(result);
}
static void shuffleBytes(int[] bytes, String encoding) {
for (int i = 0; i < 4; i++) {
int index = Integer.parseInt(encoding.substring(i, i+1))-1;
int copy = bytes[i];
bytes[i] = bytes[index];
bytes[index] = copy;
}
}
}
Fixing your current solution
There are two problems:
1. Forgot to right-align bytes
In ...
int[] bytes = {
(int)(bitMask[0] & n),
(int)(bitMask[1] & n),
(int)(bitMask[2] & n),
(int)(bitMask[3] & n)
};
... you forgot to shift each "byte" to the right. As a result, you end up with a list of "bytes" of the form 0x……000000, 0x00……0000, 0x0000……00, 0x000000……. This is not a problem yet, but after shuffleBytes you shift each of these entries again using bytes[i] = bytes[i] << (i * 8);. As a result, the relevant parts (__) end up at a completely different spot or are shifted completely out of the integer.
To fix this, shift each (int)(bitMask[…] & n) to the right:
int[] bytes = {
(int)(bitMask[0] & n) >> (3*8),
(int)(bitMask[1] & n) >> (2*8),
(int)(bitMask[2] & n) >> (1*8),
(int)(bitMask[3] & n) >> (0*8)
};
2. Swapping more than once
In ...
static void shuffleBytes(int[] bytes, String encoding) {
for (int i = 0; i < 4; i++) {
int index = Integer.parseInt(encoding.substring(i, i+1))-1;
int copy = bytes[i];
bytes[i] = bytes[index];
bytes[index] = copy;
}
}
... you swap some bytes multiple times because you operate in-place. To understand what happens consider the following minimal example where we want to swap two bytes using order = "21". We inspect the variables before/after each iteration of the for loop.
The original input is bytes = {x, y} and order = "21"
We moved bytes[0] to bytes[1]. Now we have bytes = {y, x}.
But we are not finished yet. The loop continues and moves bytes[1] to bytes[0]. You assumed that bytes[1] would still be y at this point. However, because of the previous iteration this entry now holds x instead. Therefore, the result is bytes = {x, y}.
Here nothing changed, but for more entries you might also end up with something that is neither the original order nor the expected output order.
The easiest way to fix this is to write the result into a new array:
static int[] shuffleBytes(int[] bytes, String encoding) {
int[] result = new int[bytes.length];
for (int i = 0; i < 4; i++) {
int index = Integer.parseInt(encoding.substring(i, i+1))-1;
result[index] = bytes[i];
}
return result; // also adapt main() to use this return value
}
Alternative Solution
Even though you could fix your solution as described above I'm not too happy with it. Therefore, I propose this alternative solution which is cleaner, shorter, and more efficient.
import java.util.Scanner;
public class Encoding {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int input = sc.nextInt();
System.out.format("input = 0x%08x = %1$d%n", input);
String newOrder = sc.next();
int output = reorder(input, newOrder);
System.out.format("output = 0x%08x = %1$d%n", output);
}
/** #param newOrder permutation of "1234" */
static int reorder(int input, String newOrder) {
int output = 0;
for (char byte1Based : newOrder.toCharArray()) {
output <<= 8;
int shift = (byte1Based - '1') * 8;
output |= ((0xFF << shift) & input) >> shift;
}
return output;
}
}
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.
I have a peculiar problem for which I am looking for an efficient solution. I have a byte array which contains the most significant n bytes of an unsigned 4 byte integer (most sig byte first). The value of the remaining bytes (if any) are unknown. I need to check whether the partially known integer value could fall within a certain range (+ or - x) of a known integer. It's also valid for the integer represented by the byte array under test to wrap around.
I have a solution which works (below). The problem is that this solution performs way more comparisons than I believe is necessary and a whole load of comparisons will be duplicated in the scenario in which least sig bytes are unknown. I'm pretty sure it can be done more efficiently but can't figure out how. The scenario in which least significant bytes are unknown is an edge case so I might be able to live with it but it forms part of a system which needs to have low latency so if anyone could help with this that would be great.
Thanks in advance.
static final int BYTES_IN_INT = 4;
static final int BYTE_SHIFT = 010;
// partial integer byte array length guaranteed to be 1-4 so no checking necessary
static boolean checkPartialIntegerInRange(byte[] partialIntegerBytes, int expectedValue, int range)
{
boolean inRange = false;
if(partialIntegerBytes.length == BYTES_IN_INT)
{
// normal scenario, all bytes known
inRange = Math.abs(ByteBuffer.wrap(partialIntegerBytes).getInt() - expectedValue) <= range;
}
else
{
// we don't know least significant bytes, could have any value
// need to check if partially known int could lie in the range
int partialInteger = 0;
int mask = 0;
// build partial int and mask
for (int i = 0; i < partialIntegerBytes.length; i++)
{
int shift = ((BYTES_IN_INT - 1) - i) * BYTE_SHIFT;
// shift bytes to correct position
partialInteger |= (partialIntegerBytes[i] << shift);
// build up mask to mask off expected value for comparison
mask |= (0xFF << shift);
}
// check partial int falls in range
for (int i = -(range); i <= range; i++)
{
if (partialInteger == ((expectedValue + i) & mask))
{
inRange = true;
break;
}
}
}
return inRange;
}
EDIT: Thanks to the contributors below. Here is my new solution. Comments welcome.
static final int BYTES_IN_INT = 4;
static final int BYTE_SHIFT = 010;
static final int UBYTE_MASK = 0xFF;
static final long UINT_MASK = 0xFFFFFFFFl;
public static boolean checkPartialIntegerInRange(byte[] partialIntegerBytes, int expectedValue, int range)
{
boolean inRange;
if(partialIntegerBytes.length == BYTES_IN_INT)
{
inRange = Math.abs(ByteBuffer.wrap(partialIntegerBytes).getInt() - expectedValue) <= range;
}
else
{
int partialIntegerMin = 0;
int partialIntegerMax = 0;
for(int i=0; i < BYTES_IN_INT; i++)
{
int shift = ((BYTES_IN_INT - 1) - i) * BYTE_SHIFT;
if(i < partialIntegerBytes.length)
{
partialIntegerMin |= (((partialIntegerBytes[i] & UBYTE_MASK) << shift));
partialIntegerMax = partialIntegerMin;
}
else
{
partialIntegerMax |=(UBYTE_MASK << shift);
}
}
long partialMinUnsigned = partialIntegerMin & UINT_MASK;
long partialMaxUnsigned = partialIntegerMax & UINT_MASK;
long rangeMinUnsigned = (expectedValue - range) & UINT_MASK;
long rangeMaxUnsigned = (expectedValue + range) & UINT_MASK;
if(rangeMinUnsigned <= rangeMaxUnsigned)
{
inRange = partialMinUnsigned <= rangeMaxUnsigned && partialMaxUnsigned >= rangeMinUnsigned;
}
else
{
inRange = partialMinUnsigned <= rangeMaxUnsigned || partialMaxUnsigned >= rangeMinUnsigned;
}
}
return inRange;
}
Suppose you have one clockwise interval (x, y) and one normal interval (low, high) (each including their endpoints), determining whether they intersect can be done as (not tested):
if (x <= y) {
// (x, y) is a normal interval, use normal interval intersect
return low <= y && high >= x;
}
else {
// (x, y) wraps
return low <= y || high >= x;
}
To compare as unsigned integers, you can use longs (cast up with x & 0xffffffffL to counteract sign-extension) or Integer.compareUnsigned (in newer versions of Java) or, if you prefer you can add/subtract/xor both operands with Integer.MIN_VALUE.
Convert your unsigned bytes to an integer. Right-shift by 32-n (so your meaningful bytes are the min bytes). Right-shift your min/max integers by the same amount. If your shifted test value is equal to either shifted integer, it might be in the range. If it's between them, it's definitely in the range.
Presumably the sign bit on your integers is always zero (if not, just forcibly convert the negative to zero, since your test value can't be negative). But because that's only one bit, unless you were given all 32 bits as n, that shouldn't matter (it's not much of a problem in that special case).
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