【问题标题】:24 bit signed data type [closed]24 位有符号数据类型
【发布时间】:2016-07-06 13:06:02
【问题描述】:

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

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

提前感谢您的帮助!

【问题讨论】:

  • 您确定硬件附带的程序计算出正确的否定结果吗?
  • @MoralesBatovski,问题不是“为什么这段代码不起作用?”,而是“这个黑盒程序在做什么?”。
  • “知道的价值观”看起来很奇怪,你从哪里得到的?我怀疑这是一个转换问题,有时它们小于 2-complent,有时更高
  • 您给出的对应关系与符号位和每个值位具有一致位值的任何单个整数格式都不一致。因此,我倾向于猜测执行转换的程序由于某种原因正在失去精度。
  • 代码将ubox设置为什么模式?通信协议是否设置为:NEMA。 UBX,时间脉冲,到底是什么?您的软件设置使用什么波特率?您确实需要发布您的代码,以便我们有机会回答您的问题。

标签: c labwindows 24-bit


【解决方案1】:

首先,你所拥有的“已知”值并不是你认为的那样:

#include <stdio.h>

static void p24(int x)
{
    printf("%8d = 0x%06X\n", 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("%d\n", i_from_24b(m57) );
    printf("%d\n", i_from_24b(m214528) );
    printf("%d\n", i_from_24b(m54215) );
    printf("%d\n", i_from_24b(m1462) );
    return 0;
}

将打印

-57
-214528
-54215
-1462

【讨论】:

  • 但这如何回答 OP 的问题?
  • @2501:实际上 CHAR_BIT >= 8,因为应用了移位后掩码。也许让函数也返回一个 int32_t。
  • 除以 256 是明确定义的,但如果要转换的值不能表示为 int32_t,则转换为 int32_t 具有实现定义的行为。您依赖于该实现定义的行为的特定选择。
  • 另外,这个程序转换的数据不是OP呈现的数据。
  • @datenwolf,OP 已经承认已知值与 2s 补码不匹配。这似乎是问题的重点。
【解决方案2】:

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

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

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

【讨论】:

  • 正是这个!学了这么多年微积分什么的,还是没想到精度范围!
【解决方案3】:

感谢大家的帮助,但我才意识到我是智障,甚至更智障!我从中得到“已知值”的程序显示了测量数据的缩放值,似乎+-1 +-2偏差在转换后相同的0.001精度显示值的范围内,所以它确实使用了2s补码.

抱歉大家耽误了时间! (太棒了)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 2011-07-27
    • 2015-03-24
    • 2019-05-23
    • 2014-05-15
    • 1970-01-01
    • 2012-11-12
    相关资源
    最近更新 更多