1

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?

3
  • 1
    Why are you reading a double to start with? Surely you'd be better off using Long.reverseBytes(in.readLong()). Commented Aug 4, 2014 at 14:02
  • I have to agree. If you read the double with the bytes in the wrong order, it is possible that there is some normalization that occurs which is changing the bits before you get them to reverse them. Commented Aug 4, 2014 at 14:03
  • Added this as an answer, given that I suspect it's the problem... Commented Aug 4, 2014 at 14:04

2 Answers 2

4

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()));
Sign up to request clarification or add additional context in comments.

1 Comment

doubleToLongBits definetly changes NaN to a canonical representation, its explicitly stated to do so in the javadocs: docs.oracle.com/javase/8/docs/api/java/lang/…
1

Have found the bug. Instead of

Long.reverseBytes(Double.doubleToLongBits(in.readDouble())

just needed to read as follows:

Long.reverseBytes(in.readLong())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.