在CC++中计算原始位序列的二补。

问题描述 投票:0回答:1

我想解码一条GPS导航信息,其中有些参数是这样标示的。

这样标示的参数应该是两个补码,符号位(+或-)占MSB。

例如,我想存储一个参数 af0 其中有22个位,22位为MSB。参数 af0 已经被我解码了,现在我需要进行二的补码操作。我存储了 af0 用一个 uint32_t 整数类型。

还有其他参数,如 IDOT 它有14个位数,我用一个 uint16_t.

我不确定,但如果我的理解是正确的,如果要检查MSB为 10. 如果是 1 我可以简单地通过否定(和铸造)值来计算二者的互补,即:. int32_t af0_i = -(int32_t)af0. 如果MSB是 0 我只是根据数值投。int32_t af0_i = (int32_t)af0.

这样做对吗?uintX_t 整数类型?我也试了一下。https:/stackoverflow.coma340768666518689。 但它并没有解决我的问题,数值还是一样。

c++ types binary bit-manipulation twos-complement
1个回答
0
投票

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;

上面的代码保证了符号扩展的功能 自C++20以来在这之前,它已经被实现定义了(在x86上将会像预期的那样工作,尽管你可以添加一个叫做 static_assert 为此)。)

© www.soinside.com 2019 - 2024. All rights reserved.