创建二进制世界表示形式-如何在Long中设置位然后打印Long

时间:2018-12-22 16:43:42

标签: java

我正在使用Java为Conway's Game of Life建模。我先设置好一点,然后再打印。

我当前的setCell方法正在更改指定的位以及该位索引之后的所有位,而不只是更改指定索引处的位。

我需要如何更改班级?

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();
}
}
  

预期的打印输出:

The current world:

 _  #  _  _  _  _  _  _ 
 _  #  _  _  #  #  #  _ 
 _  #  _  _  _  _  _  _ 
 _  _  _  _  _  _  _  _ 
 _  _  _  _  _  #  _  _ 
 #  #  #  _  _  #  _  _ 
 _  _  _  _  _  #  _  _ 
 _  _  _  _  _  _  _  _ 

Binary rep before setCell = 100000001001110010000000000000000000100111001000000010
31
Binary rep after setCell = 100000001001110010000010000000000000100111001000000010

The current world:

 _  #  _  _  _  _  _  _ 
 _  #  _  _  #  #  #  _ 
 _  #  _  _  _  _  _  _ 
 _  _  _  _  _  _  _  # 
 _  _  _  _  _  #  _  _ 
 #  #  #  _  _  #  _  _ 
 _  _  _  _  _  #  _  _ 
 _  _  _  _  _  _  _  _  

  

实际打印输出:

The current world:

 _  #  _  _  _  _  _  _ 
 _  #  _  _  #  #  #  _ 
 _  #  _  _  _  _  _  _ 
 _  _  _  _  _  _  _  _ 
 _  _  _  _  _  #  _  _ 
 #  #  #  _  _  #  _  _ 
 _  _  _  _  _  #  _  _ 
 _  _  _  _  _  _  _  _ 

Binary rep before setCell = 100000001001110010000000000000000000100111001000000010
31
Binary rep after setCell = 1111111111111111111111111111111110000000000000100111001000000010

The current world:

 _  #  _  _  _  _  _  _ 
 _  #  _  _  #  #  #  _ 
 _  #  _  _  _  _  _  _ 
 _  _  _  _  _  _  _  # 
 #  #  #  #  #  #  #  # 
 #  #  #  #  #  #  #  # 
 #  #  #  #  #  #  #  # 
 #  #  #  #  #  #  #  # 

(请注意,我在上面的文本中添加了一些换行符,以使我的问题更易于阅读)

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

  

问题是1 <<索引是int操作,而不是long   操作。

这对 Andreas 是正确的。我想补充一点,您在3个地方使用索引计算,但是这个问题仅出现在其中一个地方。我认为您可以将其提取为单独的方法并使用它。可能会更清楚。

// 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;
}

然后您可以简化代码:

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);
}

答案 1 :(得分:0)

问题在于1 << indexint操作,而不是long操作。

使用输入col = 7, row = 3,计算index = col + (row * side_length)产生值31,该值在int中是符号位

world |= (1 << index)然后使用 sign-extension int的值扩展为long,并将所有高32位设置为1。

将代码更改为world |= (1L << index),因此将移位作为long完成。这样,它也可以为index值大于31的情况工作。