从uint16_t转换到int16_t

时间:2017-02-08 20:47:38

标签: c casting buffer shift

我有一个关于铸造和换挡的noob问题。我正在尝试将数组中uint8_t的两个元素存储为类型为int16_t的数组中的单个有符号元素。但是我的结果不正确,我不知道为什么。

我有这段代码:

uint8_t buffer[BUFFER_SIZE];
int16_t mp3_stereo_buffer[BUFFER_SIZE];

for (i = 0; i < BUFFER_SIZE; i += 2) {
    mp3_stereo_buffer[i] = ((uint16_t)buffer[i] << 8) | ((uint16_t)buffer[i + 1]);
}

2 个答案:

答案 0 :(得分:1)

首先,您可以将N uint8_t打包成N / 2 uint16_t个元素。

uint8_t buffer[BUFFER_SIZE];
uint16_t mp3_stereo_buffer[BUFFER_SIZE / 2];

然后你需要知道你的数据是小端还是大端。

对于little-endian:

for (i = 0; i < BUFFER_SIZE / 2; i++) {
  mp3_stereo_buffer[i] = (uint16_t) (buffer[i*2] | (buffer[i*2+1] << 8));
}

对于big-endian:

for (i = 0; i < BUFFER_SIZE / 2; i++) {
  mp3_stereo_buffer[i] = (uint16_t) ((buffer[i*2] << 8) | buffer[i*2+1]);
}

P.S。如果您的数据实际上是签名的,那么您可以将类型和转换更改为int16_t,但要注意表示签名数字的方式并不保证是可移植的。

答案 1 :(得分:0)

#define LITTLE_ENDIAN
int main()
{
uint8_t buffer[4]={0x15,0xff,0x63,0xee};
int16_t mp3_stereo_buffer[2];

for (int i = 0; i < 2; i += 1) {
    mp3_stereo_buffer[i] = ((int16_t*)buffer)[i];

#ifdef LITTLE_ENDIAN
    mp3_stereo_buffer[i]=(mp3_stereo_buffer[i]>>8 &0x00ff) | (mp3_stereo_buffer[i]<<8 & 0xff00);              
#endif

    printf("%x\n",mp3_stereo_buffer[i]&0xffff);
 }
return 0;
}