如何在位掩码中使用有符号整数类型的每一位?

时间:2016-03-15 19:28:13

标签: java long-integer binary-data bitmask

我在尝试使用java签名的长整数来存储64位布尔数据时遇到了一个奇怪的错误。正确地设置和测试这些值,除了(位&(1<< n))> 0 为真的每一位,n 32更高的值也是莫名其妙的真实(非零)。

我认为这是翻转的结果,但我不熟悉java如何在内部处理符号位和翻转。这种类型的操作在其他语言中只使用有符号整数类型。

我的位操作的伪代码:

// this is for manipulating minecraft world chunks directly, if anyone is wondering what the point is. 
// there is really no higher-level alternative that wont use vast amounts of memory and time.
long[][][] bits = new long[16][16][4]; // an array of long bitfields, each representing 64 blocks along Y-axis
                    // 16x16x(4x64) is 65536 blocks, or one chunk
                    // bits[ column-x ][ column-z ][ slices-y ]  - fairly basic format


// set a bit (this all works fine, i have tested the results)
long nb = ( (long)1 << (b.getY()%64) ); // the new bit to be set.
//(a % b + b) % b fixes issues with java modulus giving negative results for negative values of a
bits[(b.getX()%16 + 16)%16][(b.getZ()%16+16)%16][b.getY()/64] |= nb; 
// set the relighting bit for the block


// This is the bug.
//Loops through n=63 to n=0
b = one of the longs from bits[][][]
n=64;
while(--n>-1)
    if( (b & (1<<n)) > 0 )....
//  this evaluates correctly to nonzero for the expected bit, but also for every value of n 32 higher than each expected one.
// IE; if the 4th bit is set, b & (1<<3) is nonzero, but b & (1<<35) also tests nonzero. i have debugged the bitmasks before the operation and confirmed that only the correct bit is set.

// the resulting value of b & (1<<n) is the same for the correct value and for the value 32 bits farther along.

1 个答案:

答案 0 :(得分:1)

在代码末尾的if语句中

(1<<n)

需要

(1L<<n)