java reading 2 byte integer in 2's complement from binary file into integer

I am trying to parse a binary file containing values. In the specs it says that each value is represented as a 2-byte integer in 2's complement format. I am reading the file into a byte array called 'data':

int i = (data[i] & 0xff) | (short) (data[i+1] << 8);

The values look fine however when I try to write them back into the file:

byte a = (byte)((tempInt >> 8) & 0xff);
byte b = (byte)(tempInt & 0xff);

'tempInt' being the value in int.

When I read in the file that I wrote, not all of the values are the same. Some of them but not all.

Am I missing something here?

UPDATE: I plottet the values for comparison. The top half are the values that i read from the file. The bottom half are the values that i read from the file, then wrote to a new file and then read again. plot I think that the graphs look too similar for it to be completely wrong.

UPDATE #2: the bytes i read from the input file:

0, 0, 59, 36, 40, 36, 23, 36, 54, 36, 54, 36, 41, 36, 46, 36, 50, 36, 52, 36, 79, 36, 79, 36, 66, 36, 65, 36, 58, 36, 58, 36, 58, 36, 45, 36, 51, 36, 65, 36, 65, 36, 76, 36, 78, 36, 69, 36, 54, 36, 68, 36, 86, 36, 85, 36, 81, 36, 81, 36, 80, 36, 84, 36, 84, 36, 80, 36, 82, 36, 85, 36, 81, 36, 80, 36, 75, 36, 75, 36, 79, 36, 91, 36, 83, 36, 64, 36, 71, 36, 79, 36, 56, 36, 38, 36, 47, 36, 51, 36, 41, 36, 48, 36, 63, 36, 56, 36, 50, 36, 57, 36, 67, 36, 78, 36, 81, 36, 67, 36, 81, 36, 81, 36, 82, 36, 69, 36, 66, 36, 66, 36, 54, 36, 39, 36, 78, 36, 78, 36, 78, 36, 62, 36, 57, 36, 73, 36, 75, 36, 69, 36, 76, 36, 81, 36, 74, 36

Converted integers:

0, 9275, 9256, 9239, 9270, 9270, 9257, 9262, 9266, 9268, 9295, 9295, 9282, 9281, 9274, 9274, 9274, 9261, 9267, 9281, 9281, 9292, 9294, 9285, 9270, 9284, 9302, 9301, 9297, 9297, 9296, 9300, 9300, 9296, 9298, 9301, 9297, 9296, 9291, 9291, 9295, 9307, 9299, 9280, 9287, 9295, 9272, 9254, 9263, 9267, 9257, 9264, 9279, 9272, 9266, 9273, 9283, 9294, 9297, 9283, 9297, 9297, 9298, 9285, 9282, 9282, 9270, 9255, 9294, 9294, 9294, 9278, 9273, 9289, 9291, 9285, 9292, 9297, 9290

the bytes i read from the file that i wrote from the above values:

32, 0, 0, 36, 59, 36, 40, 36, 23, 36, 54, 36, 54, 36, 41, 36, 46, 36, 50, 36, 52, 36, 79, 36, 79, 36, 66, 36, 65, 36, 58, 36, 58, 36, 58, 36, 45, 36, 51, 36, 65, 36, 65, 36, 76, 36, 78, 36, 69, 36, 54, 36, 68, 36, 86, 36, 85, 36, 81, 36, 81, 36, 80, 36, 84, 36, 84, 36, 80, 36, 82, 36, 85, 36, 81, 36, 80, 36, 75, 36, 75, 36, 79, 36, 91, 36, 83, 36, 64, 36, 71, 36, 79, 36, 56, 36, 38, 36, 47, 36, 51, 36, 41, 36, 48, 36, 63, 36, 56, 36, 50, 36, 57, 36, 67, 36, 78, 36, 81, 36, 67, 36, 81, 36, 81, 36, 82, 36, 69, 36, 66, 36, 66, 36, 54, 36, 39, 36, 78, 36, 78, 36, 78, 36, 62, 36, 57, 36, 73, 36, 75, 36, 69, 36, 76, 36, 81, 36

Converted integers:

32, 9216, 9275, 9256, 9239, 9270, 9270, 9257, 9262, 9266, 9268, 9295, 9295, 9282, 9281, 9274, 9274, 9274, 9261, 9267, 9281, 9281, 9292, 9294, 9285, 9270, 9284, 9302, 9301, 9297, 9297, 9296, 9300, 9300, 9296, 9298, 9301, 9297, 9296, 9291, 9291, 9295, 9307, 9299, 9280, 9287, 9295, 9272, 9254, 9263, 9267, 9257, 9264, 9279, 9272, 9266, 9273, 9283, 9294, 9297, 9283, 9297, 9297, 9298, 9285, 9282, 9282, 9270, 9255, 9294, 9294, 9294, 9278, 9273, 9289, 9291, 9285, 9292, 9297

UPDATE #3: I will post the code now. In order to do that will have to explain how the data is stored in the file (btw it is the EDF format).

There are 3 important components: Records, Signals and Samples.

A sample is represented as a 2-byte integer in 2's complement format and it is stored as an integer. A signal is an array of samples. However the signals are not stored consecutively in the file. This is where records come in. A record holds a predefined amount of samples from every signal. The records are stored consecutively in the file. So every record contains a part of every signal. The amount of samples is defined in the meta files, the variable holding this value is called 'nrOfSamplesPerSignalInEachRecordGlobal' in my code. So you have to loop over every record in order to cling together each signal.

Signal class:

public class Signal {
    //Attributes
    private int lengthOfValues;
    private int[] values;

    public Signal(int lengthOfValues) {
        values = new int[lengthOfValues];
    }

    public void addValue(int value, int index) {
        values[index] = value;
    }

    public int[] getValues() {
        return values;
    }

    public void setValues(int[] values) {
        this.values = values;
    }

    public int getLengthOfValues() {
        return lengthOfValues;
    }

    public void setLengthOfValues(int lengthOfValues) {
        this.lengthOfValues = lengthOfValues;
    }

}

This is the function that stores the bytes from the file into the signals data structure:

    public Signal[] storeSignals(byte[] data) {
        Signal[] signals = new Signal[signalCount];
        for (int i = 0; i < signals.length; i++) {
            signals[i] = new Signal(nrOfSamplesPerSignalInEachRecordGlobal[i]*recordsCount);
        }
        //interates through the records
        for (int i = 0; i < recordsCount; i++) {
            //iterates through the signals
            for (int j = 0; j < signalCount; j++) {
                //int offsetBytes = i*signalsInEachRecordsInBytes;
                int offsetBytes = 0;
                for(int l = 0; l < j; l++) {
                    offsetBytes = offsetBytes + nrOfSamplesPerSignalInEachRecordGlobal[l];
                }
                offsetBytes = offsetBytes + i*signalCount*nrOfSamplesPerSignalInEachRecordGlobal[j];
                int offsetSignalIndex = i*nrOfSamplesPerSignalInEachRecordGlobal[j];
                //iterates through the samples
                for (int k = 0; k < nrOfSamplesPerSignalInEachRecordGlobal[j]; k++) {
                    signals[j].addValue((short)(data[2 * (offsetBytes + k)] & 0xff) | (short) (data[2 * (offsetBytes + k) + 1] << 8), offsetSignalIndex + k);
                }
            }
        }
        return signals;
    }

this is the function that writes the samples back to bytes:

    public List<Byte> writeData(List<Byte> bytes, AbstractFile edfFile) {
        int a = bytes.size();
        int[] offsetStart = new int[edfFile.getSignals().length];
        Arrays.fill(offsetStart, 0);
        int[] offsetEnd = new int[edfFile.getSignals().length];

        for(int i = 0; i < edfFile.getSignals().length; i++) {
            offsetEnd[i] = edfFile.getNrOfSamplesPerSignalInEachRecords()[i];
        }

        for (int i = 0; i < edfFile.getNumberOfDataRecords(); i++) {
            for (int j = 0; j < edfFile.getSignals().length; j++) {
                bytes = convertToByte(edfFile, bytes, j, offsetStart[j], offsetEnd[j]);
                offsetStart[j] = offsetStart[j] + edfFile.getNrOfSamplesPerSignalInEachRecords()[j];
                offsetEnd[j] = offsetEnd[j] + edfFile.getNrOfSamplesPerSignalInEachRecords()[j];
            }
        }

        return bytes;
    }


     public List<Byte> convertToByte(AbstractFile edfFile, List<Byte> bytes, int signalIndex, int start, int end) {
        for (int i = start; i < end; i++) {
            int tempInt = edfFile.getSignals()[signalIndex].getValues()[i];

            bytes.add((byte)((tempInt >> 8) & 0xff));
            bytes.add((byte)(tempInt & 0xff));

        }
        return bytes;
    }
Jon Skeet
people
quotationmark

Yes - you're reading them in little-endian format (the first value is the least important) but you're writing them in big-endian format (the first value is the most important), assuming you're writing a then b.

Just reverse the order when you write them, assuming the file is meant to be little-endian:

byte a = (byte)(tempInt & 0xff);
byte b = (byte)((tempInt >> 8) & 0xff);

people

See more on this question at Stackoverflow