我在尝试使用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.
答案 0 :(得分:1)
在代码末尾的if语句中
(1<<n)
需要
(1L<<n)