Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't ByteBuffer preserve index for putDouble and getDouble?

I'm having difficulty understanding the semantics of ByteBuffer in the following scenario:

int sizeOfDouble = 8;
int numberOfDoubles = 4;
ByteBuffer testBuf = ByteBuffer.allocateDirect(sizeOfDouble*numberOfDoubles);

testBuf.putDouble(0, 1.0);
testBuf.putDouble(1, 2.0);
testBuf.putDouble(2, 3.0);
testBuf.putDouble(3, 4.0);

for (int i = 0; i < numberOfDoubles; ++i) {
    System.out.println("testBuf[" + i + "]: " + testBuf.getDouble(i));
}

I expected to see the values I had just put into the ByteBuffer to be printed to the screen. Instead, I get this output:

testBuf[0]: 4.959404759574682E-4
testBuf[1]: 32.50048828125
testBuf[2]: 32.125
testBuf[3]: 4.0

The value at the third index seems to match what I expect: 4.0. But why aren't the values and indices 0, 1, and 2 matching up with the values I inserted (1.0, 2.0, and 3.0, respectively)?

I suspect I misunderstand something about how ByteBuffer works, but I haven't been able to find it in the javadoc.

like image 904
Kirby Avatar asked Dec 24 '22 09:12

Kirby


1 Answers

This is because your code treats index as an index in an array of doubles. The initial write completes successfully; then the second one writes over its bytes except the first one; the third write overwrites the bytes again, and so on. The results of the last write don't get written over, so 4.0 comes out intact.

The first argument represents an index into the array of bytes inside the buffer, so you need to multiply it by sizeOfDouble:

testBuf.putDouble(0*sizeOfDouble, 1.0);
testBuf.putDouble(1*sizeOfDouble, 2.0);
testBuf.putDouble(2*sizeOfDouble, 3.0);
testBuf.putDouble(3*sizeOfDouble, 4.0);

for (int i = 0; i < numberOfDoubles; ++i) {
    System.out.println("testBuf[" + i + "]: " + testBuf.getDouble(sizeOfDouble*i));
}

Demo.

like image 168
Sergey Kalinichenko Avatar answered Feb 15 '23 09:02

Sergey Kalinichenko