KBriggs KBriggs - 2 years ago 79
C Question

reading big-endian files in little-endian system

I have a data file that I need to read in C. It is compirsed of alternating 16-bit integer stored in binary form, and I need only the first column (ie, every other entry starting at 0)

I have a simple python script that reads the files accurately:

import numpy as np

fname = '[filename]'
columntypes = np.dtype([('curr_pA', '>i2'),('volts', '>i2')])
test = np.memmap(fname, dtype=columntypes,mode='r')['curr_pA']

I want to port this to C. Because my machine is natively little-endian I need to manually perform the byte swap. Here's what I have done:

void swapByteOrder_int16(double *current, int16_t *rawsignal, int64_t length)
int64_t i;
for (i=0; i<length; i++)
current[i] = ((rawsignal[2*i] << 8) | ((rawsignal[2*i] >> 8) & 0xFF));

int64_t read_current_int16(FILE *input, double *current, int16_t *rawsignal, int64_t position, int64_t length)
int64_t test;

int64_t read = 0;

if (fseeko64(input,(off64_t) position*2*sizeof(int16_t),SEEK_SET))
return 0;
test = fread(rawsignal, sizeof(int16_t), 2*length, input);
read = test/2;
if (test != 2*length)
perror("End of file reached");
swapByteOrder_int16(current, rawsignal, length);
return read;

In the
function I use
to read a large chunk of data (both columns) into
array. I then call
to pick off every other value, and swap its bytes around. I then cast the result to
and store it in

It doesn't work. I get garbage as the output in the C code. I think I've been starting at it for too long and can no longer see my own errors. Can anyone spot anything glaringly wrong?

Answer Source

Perform the endian swap as unsigned math and then assign to double.

void swapByteOrder_int16(double *current, const int16_t *rawsignal, size_t length) {
    for (size_t i = 0; i < length; i++) {
      int16_t x = rawsignal[2*i];
      x = (x*1u << 8) | (x*1u >> 8);
      current[i] = x;
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download