C - 24 位有符号数据类型



我正在从ublox GPS模块接收24位长位域(4字节消息的3个字节)的数据,我需要将这些24位数据字段转换为有符号十进制值,但我在规范中找不到如何执行此操作的说明。我也知道模块附带的另一个程序的某些值。

对于正值,似乎它只是简单地将 24 位二进制数转换为 dec,仅此而已,例如 0x000C19 = 30970x000BD0 = 3024,但对于负数,我遇到了麻烦。2 的补码似乎不起作用。以下是一些已知值:0xFFFFC8 = -570xFCB9FE = -2145280xFF2C3B = -542150xFFFA48 = -1462。使用 2 的补码,每次转换都是几个数字(分别为 -56、-214530、-54213、-1464)。(十六进制数字用于避免每次都写入 24 位数字。

提前感谢您的帮助!

首先,您拥有的"已知"值并不是您认为的那样:

#include <stdio.h>
static void p24(int x)
{
    printf("%8d = 0x%06Xn", x, (0x00ffffff & (unsigned)x));
}
int main(int argc, char *argv[])
{
    p24(-57);
    p24(-214528);
    p24(-54215);
    p24(-1462);
    return 0;
}

在 2s 补码机上编译和运行打印

     -57 = 0xFFFFC7
 -214528 = 0xFCBA00
  -54215 = 0xFF2C39
   -1462 = 0xFFFA4A

当转换为 2s 补码时,您当然必须填充到您正在使用的目标数据类型的整个长度,以便正确继承符号。然后将有符号数据类型划分为设计的位数。

前任:

#include <stdio.h>
#include <stdint.h>
/* 24 bits big endian */
static char const m57[]     = {0xFF, 0xFF, 0xC7};
static char const m214528[] = {0xFC, 0xBA, 0x00};
static char const m54215[]  = {0xFF, 0x2C, 0x39};
static char const m1462[]   = {0xFF, 0xFA, 0x4A};
static
int32_t i_from_24b(char const *b)
{
    return (int32_t)(
        (((uint32_t)b[0] << 24) & 0xFF000000)
      | (((uint32_t)b[1] << 16) & 0x00FF0000)
      | (((uint32_t)b[2] <<  8) & 0x0000FF00)
    ) / 256;
}
int main(int argc, char *argv[])
{
    printf("%dn", i_from_24b(m57) );
    printf("%dn", i_from_24b(m214528) );
    printf("%dn", i_from_24b(m54215) );
    printf("%dn", i_from_24b(m1462) );
    return 0;
}

将打印

-57
-214528
-54215
-1462

OP 的信息不一致,可能@John布林注释适用:" ...执行转换的程序正在失去精度..."

OP 需要审查并发布更多信息/代码。

OP's        OP's    2's comp.   Diff
Hex         Dec     
0xFFFFC8    -57     -56        -1
0xFCB9FE    -214528 -214530     2
0xFF2C3B    -54215  -54213     -2
0xFFFA48    -1462   -1464       2

由于此评论的复杂性,作为答案发布

感谢大家的帮助,但我刚刚意识到我是智障,甚至更迟钝!我从中获取"已知值"的程序显示了测量数据的缩放值,并且似乎 +-1 +-2 偏差在转换后相同的 0.001 精度显示值范围内,因此它确实使用了 2s 补码。

对不起,大家浪费了时间!(所以真棒)

相关内容

  • 没有找到相关文章

最新更新