【发布时间】:2016-09-21 16:53:17
【问题描述】:
我有一个需要用 C 语言读取的数据文件。它由以二进制形式存储的交替 16 位整数组成,我只需要第一列(即从 0 开始的每隔一个条目)
我有一个简单的 python 脚本可以准确读取文件:
import numpy as np
fname = '[filename]'
columntypes = np.dtype([('curr_pA', '>i2'),('volts', '>i2')])
test = np.memmap(fname, dtype=columntypes,mode='r')['curr_pA']
我想将它移植到 C。因为我的机器本身是 little-endian,所以我需要手动执行字节交换。这是我所做的:
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;
}
在read_current_int16 函数中,我使用fread 将大量数据(两列)读入rawsignal 数组。然后我调用swapByteOrder_int16 来挑选所有其他值,并交换它的字节。然后我将结果转换为double 并将其存储在current。
它不起作用。我得到垃圾作为 C 代码中的输出。我想我已经开始太久了,再也看不到自己的错误了。谁能发现明显的错误?
【问题讨论】:
-
为什么代码在
swapByteOrder_int16(double *current, int16_t *rawsignal, int64_t length)中使用double而不是int16_t? -
其余代码使用
double处理代码I/O部分的输出。由于我从int16_t转换为double,因此应该不会损失精度。对current[i]的赋值中有一个隐式转换。 -
rawsignal[2*i]表示输入是每整数 32 位。现在,如果它们也被交换了,你应该使用rawsignal[2*(i+1)-1]使用调试器来检查发生了什么。 -
rawsignal应该是未签名的。否则>> 8可能会移动 1 位(符号扩展)。 -
您可能不需要将此移植到 C。请参阅
numpy文档中的 Byte-swapping Introduction to byte ordering and ndarrays。
标签: c endianness