Reputation: 61
I am getting a strange error while attempting to use a java signed long integer to store 64 bits of boolean data. The values are being set and tested correctly, except for every bit where (bits & (1 << n)) >0 is true, a value of n 32 higher is also inexplicably true (nonzero).
I am thinking this is a result of rollover somehow, but i am not familiar with how java handles sign bits and rollover internally. this same sort of operation has worked fine in other languages with only signed integer types.
Pseudocode for my bit operations:
// 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.
Upvotes: 1
Views: 188
Reputation: 13289
In the if statement towards the end of the code
(1<<n)
needs to be
(1L<<n)
Upvotes: 1