gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 16:46:35 26 4
gpt4 key购买 nike

我正在使用一个加速度计在嵌入式 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); 我如何实现我想要的结果?

数学在纸面上是可行的,但我觉得编译器出于某种原因与我作对:(。

最佳答案

将 14 位 2 的补码值转换为 16 位有符号,同时保持该值仅需以下几步:

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

左移将符号位插入 16 位符号位位置,除以四恢复大小但保持其符号。除法避免了右移的实现定义行为,但通常会在允许的指令集上导致单个算术右移。强制转换是必要的,因为 raw << 2是一个 int表达式,除非 int是 16 位,除法将简单地恢复原始值。

不过,将加速度计数据左移两位并将其视为传感器最初是 16 位会更简单。将所有内容标准化为 16 位的好处是,如果您使用最多 16 位的传感器,则无需更改代码。幅度只会增加四倍,最低有效两位将为零 - 无信息是增益还是损失,在任何情况下缩放都是任意的。

int16_t accel = raw << 2 ;

在这两种情况下,如果您想要无符号的大小,那么这很简单:

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

关于将原始 14 位二进制补码转换为带符号的 16 位整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34075922/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com