Reputation: 533
I have a file which consist of Delphi records. The record looks like:
TPoint = record
X, Y: Double;
end;
As I know Delphi stores data as LittleEndian, and Java as BigEndian so the read method looks like:
public Point readPoint() throws IOException {
double x = Double.longBitsToDouble(
Long.reverseBytes(
Double.doubleToLongBits(in.readDouble()
)
)
);
double y = Double.longBitsToDouble(
Long.reverseBytes(
Double.doubleToLongBits(in.readDouble()
)
)
);
return new Point(x, y);
}
Everything seemed to be fine but sometimes I take the corrupted data. I got
638 offset: 10256 Point{x=3.143E-319, y=48.47134}
But should to get
638 offset: 10256 Point{x=22.25315, y=48.47134}
When I opened the file and look the data with offset 10256 I see:
7F FB 3A 70 CE 40 36 40
which is 22.25315 in LittleEndian. So i wondered what is the problem? Is there any problem with Long.reverseBytes() method? Or it's impossible to convert any doubles from LE to BE and vice versa?
Upvotes: 1
Views: 279
Reputation: 533
Have found the bug. Instead of
Long.reverseBytes(Double.doubleToLongBits(in.readDouble())
just needed to read as follows:
Long.reverseBytes(in.readLong())
Upvotes: 1
Reputation: 1500535
I suspect the problem may be because you're reading 8 bytes as a big-endian double
when they're not a big-endian double. Given that bits have specific meanings in double
, that could cause problems - Java may be normalizing NaN values, for example. It's a bit like reading text data using an encoding that you know is incorrect, and then converting it back into bytes...
If you read the value as a long
to start with, that should preserve all the bits, so you can reverse the bytes and then convert to a double
:
double x = Double.longBitsToDouble(Long.reverseBytes(in.readLong()));
double y = Double.longBitsToDouble(Long.reverseBytes(in.readLong()));
Upvotes: 4