Reputation:
I am using java to model Conway's Game of Life
. I am setting a bit in a long and then printing the bit.
My current setCell
method is changing the specified bit and all of the bits after that bit index, rather than just the bit at the specified index.
How do I need to change my class?
public class TinyLife {
private final int side_length = 8;
private long world;
public TinyLife(long world){
this.world = world;
}
public void printWorld(){
System.out.println("\nThe current world:");
for (int row = 0; row < side_length; row++){
for (int col = 0; col < side_length; col++){
System.out.print(getCell(col, row) ? " # " : " _ ");
}
System.out.println();
}
}
public boolean getCell(int col, int row){
int index = (row * side_length) + col;
long a = world >> index; // Shift the bits by position.
long c = a & 1;
return (c == 1);
}
public void setCell(int col, int row, boolean value) {
int index = col + (row * side_length);
System.out.println(index);
/* I think that the error is below. Why are all the bits to the left of the bit at the index also being set? */
if (value) {
world |= (1 << index);
}
else world = world & ~(1 << index);
}
public static void main(String[] args) {
long first_world = 0x20272000027202L;
TinyLife world = new TinyLife(first_world);
world.printWorld();
System.out.println("Binary rep before setCell = " + Long.toBinaryString(world.world));
world.setCell(7, 3, true);
System.out.println("Binary rep after setCell = " + Long.toBinaryString(world.world));
world.printWorld();
}
}
Expected printout:
The current world:
_ # _ _ _ _ _ _
_ # _ _ # # # _
_ # _ _ _ _ _ _
_ _ _ _ _ _ _ _
_ _ _ _ _ # _ _
# # # _ _ # _ _
_ _ _ _ _ # _ _
_ _ _ _ _ _ _ _
Binary rep before setCell = 100000001001110010000000000000000000100111001000000010
31
Binary rep after setCell = 100000001001110010000010000000000000100111001000000010
The current world:
_ # _ _ _ _ _ _
_ # _ _ # # # _
_ # _ _ _ _ _ _
_ _ _ _ _ _ _ #
_ _ _ _ _ # _ _
# # # _ _ # _ _
_ _ _ _ _ # _ _
_ _ _ _ _ _ _ _
Actual printout:
The current world:
_ # _ _ _ _ _ _
_ # _ _ # # # _
_ # _ _ _ _ _ _
_ _ _ _ _ _ _ _
_ _ _ _ _ # _ _
# # # _ _ # _ _
_ _ _ _ _ # _ _
_ _ _ _ _ _ _ _
Binary rep before setCell = 100000001001110010000000000000000000100111001000000010
31
Binary rep after setCell = 1111111111111111111111111111111110000000000000100111001000000010
The current world:
_ # _ _ _ _ _ _
_ # _ _ # # # _
_ # _ _ _ _ _ _
_ _ _ _ _ _ _ #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
(Note that I added a few line breaks to the text above to try to make my question easier to read)
Thank you very much for any help.
Upvotes: 0
Views: 50
Reputation: 18245
The problem is that 1 << index is an int operation, not a long operation.
That's correct from Andreas. I would like to add to this, that you use index calculation in 3 places, but this problem appears in only one of them. I think you could extract it to the separate method and use it. It could be more clear.
// convert given `cal` and `row` to long with single bit set
private long bit(int col, int row) {
// optionally you could add check for correct col and row (0 <= col (row) <= side_length - 1)
return 1L << (row * side_length) + col;
}
then you can simplify your code:
public boolean getCell(int col, int row) {
return (world & bit(col, row)) != 0;
}
public void setCell(int col, int row, boolean value) {
if (value)
world |= bit(col, row);
else
world &= ~bit(col, row);
}
Upvotes: 1
Reputation: 159106
The problem is that 1 << index
is an int
operation, not a long
operation.
With inputs col = 7, row = 3
, the calculation index = col + (row * side_length)
yields the value 31
, which in an int
value is the sign bit.
world |= (1 << index)
then widens the int
value to a long
using sign-extension, setting all upper 32 bits to 1's.
Change code to world |= (1L << index)
, so the bit-shift is done as a long
. That way it'll also work for index
value above 31.
Upvotes: 1