计算C / C ++中原始位序列的二进制补码

我想解码GPS导航消息,其中标记了一些参数,例如:

如此指示的参数应为二进制补码,并带有符号位 (+或-)占据MSB

例如,我要存储一个参数af0,该参数具有22个位数,其中第22位为MSB。 参数af0已由我解码,现在我需要执行两者的补码操作。我使用af0整数类型存储了uint32_t

还有其他参数,例如IDOT,它具有14位数字,我使用uint16_t存储了它。

我不确定,但是如果我理解正确,是否必须检查MSB 1 0 。如果是 1 ,我可以 只需通过取反(和强制转换)值int32_t af0_i = -(int32_t)af0来计算两者的补数。如果MSB为 0 ,我只是根据int32_t af0_i = (int32_t)af0投射值。

这对uintX_t整数类型正确吗?我还尝试了:https://stackoverflow.com/a/34076866/6518689,但它没有解决我的问题,值保持不变。

iCMS 回答:计算C / C ++中原始位序列的二进制补码

af0_i = -(int32_t)af0将无法正常工作;它将翻转所有位,而您需要对MSB进行符号扩展,其余部分保持不变。

假设您将原始的22位提取到32位变量中:

int32_t af0 = ... /* some 22-bit value,top 10 bits are 0 */;

因此,现在的第21位是符号位。但是使用int32_t时,符号位是31位(从技术上讲,直到C ++ 20才保证二进制补码)。

所以我们可以向左移10位,然后立即向右移,这将对其进行符号扩展。

af0 <<= 10; af0 >>= 10;

上面的代码保证对since C++20进行符号扩展,并且在此之前实现定义(在x86上可以按预期工作,尽管您可以为此添加static_assert)。

本文链接:https://www.f2er.com/2161301.html

大家都在问