我想解码一条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.coma340768666518689。 但它并没有解决我的问题,数值还是一样。
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
为此)。)