当前位置:  开发笔记 > 编程语言 > 正文

将原始14位二进制补码转换为有符号16位整数

如何解决《将原始14位二进制补码转换为有符号16位整数》经验,为你挑选了2个好方法。

我在嵌入式C中做了一些工作,加速度计将数据作为14位2的补码数返回.我将这个结果直接存储到一个uint16_t.稍后在我的代码中,我试图将这个"原始"形式的数据转换为有符号整数,以表示/使用我的其余代码.

我无法让编译器了解我想要做什么.在下面的代码中,我正在检查第14位是否已设置(意味着数字为负),然后我想反转这些位并加1以获得数字的大小.

int16_t fxls8471qr1_convert_raw_accel_to_mag(uint16_t raw, enum fxls8471qr1_fs_range range) {
  int16_t raw_signed;
  if(raw & _14BIT_SIGN_MASK) {
    // Convert 14 bit 2's complement to 16 bit 2's complement
    raw |= (1 << 15) | (1 << 14); // 2's complement extension
    raw_signed = -(~raw + 1);
  }
  else {
    raw_signed = raw;
  }
  uint16_t divisor;
  if(range == FXLS8471QR1_FS_RANGE_2G) {
    divisor = FS_DIV_2G;
  }
  else if(range == FXLS8471QR1_FS_RANGE_4G) {
    divisor = FS_DIV_4G;
  }
  else {
    divisor = FS_DIV_8G;
  }

  return ((int32_t)raw_signed * RAW_SCALE_FACTOR) / divisor;
}

遗憾的是,此代码不起作用.反汇编告诉我,由于某种原因,编译器正在优化我的语句raw_signed = -(~raw + 1);如何实现我想要的结果?

数学运算在纸上,但我觉得由于某种原因,编译器正在与我战斗:(.



1> Clifford..:

将14位2的补码值转换为16位有符号,同时保持该值只是以下因素:

int16_t accel = (int16_t)(raw << 2) / 4 ;

左移将符号位推入16位符号位位置,除以4会恢复幅度但保持其符号.除法避免了右移的实现定义行为,但通常会在允许的指令集上产生单个算术移位权.强制转换是必要的,因为它raw << 2是一个int表达式,除非int是16位,否则除法将简单地恢复原始值.

然而,将加速度计数据左移两位并将其视为传感器首先是16位就更简单了.将所有内容归一化到16位有一个好处,即如果你使用一个高达16位的任意位数的传感器,代码就不需要改变.幅度将只是四倍,最不重要的两位将为零 - 没有信息获得或丢失,并且在任何情况下缩放都是任意的.

int16_t accel = raw << 2 ;

在这两种情况下,如果您想要无符号幅度,那么这只是:

int32_t mag = (int32_t)labs( (int)accel ) ;


@chux:谢谢 - 修复.为了清晰起见,您的两步解决方案可能会更好.就个人而言,我真的不愿意恢复到14位幅度缩放; 这是一个不必要的步骤.

2> UncleO..:

我会做简单的算术.结果是14位有符号,表示为0到2 ^ 14-1的数字.测试数字是否为2 ^ 13或更高(表示否定)然后减去2 ^ 14.

int16_t fxls8471qr1_convert_raw_accel_to_mag(uint16_t raw, enum fxls8471qr1_fs_range range) 
{
  int16_t raw_signed = raw;
  if(raw_signed >= 1 << 13) {
    raw_signed -= 1 << 14;
  }

  uint16_t divisor;
  if(range == FXLS8471QR1_FS_RANGE_2G) {
    divisor = FS_DIV_2G;
  }
  else if(range == FXLS8471QR1_FS_RANGE_4G) {
    divisor = FS_DIV_4G;
  }
  else {
    divisor = FS_DIV_8G;
  }

  return ((int32_t)raw_signed * RAW_SCALE_FACTOR) / divisor;
}

请检查我的算术.(我有13和14正确吗?)


好吧,"政治上最优".
推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有