【问题标题】:Unsigned wrapped around Integer to the 'actual' value C无符号环绕整数到“实际”值 C
【发布时间】:2015-05-02 19:40:43
【问题描述】:

我从测试中获得了几个数字,这些数字存储为 Contiki 使用的无符号整数,用 C 语言实现(即无符号整数),并且基本上不断添加正数。

它们现在是负面的,所以我假设它们缠绕在一起。有人让我得到整数的“实际”假定值。

所有整数都低于 32768,所以我假设它在 2^15 处环绕。很多整数都接近 -32768,所以我假设它是从 32768 到 -32768。

所以基本上,如果我得到一个像 -23000 这样的整数,它的实际假定值(在我的例子中)是 (32768 + (32768 - 23000)) = 42536?

这是正确的吗?

编辑:

非常清楚,我说的是 contiki 中定义的 uipstats_t 类型。 像这样:

struct uip_stats {


 struct {
    uip_stats_t recv;     /**< Number of received packets at the IP
                 layer. */
    uip_stats_t sent;     /**< Number of sent packets at the IP
                 layer. */
    uip_stats_t forwarded;/**< Number of forwarded packets at the IP
                 layer. */
    uip_stats_t drop;     /**< Number of dropped packets at the IP
                 layer. */
    uip_stats_t vhlerr;   /**< Number of packets dropped due to wrong
                 IP version or header length. */
    uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
                 IP length, high byte. */
    uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
                 IP length, low byte. */
    uip_stats_t fragerr;  /**< Number of packets dropped because they
                 were IP fragments. */
    uip_stats_t chkerr;   /**< Number of packets dropped due to IP
                 checksum errors. */
    uip_stats_t protoerr; /**< Number of packets dropped because they
                 were neither ICMP, UDP nor TCP. */
  } ip; 

它们为我的平台定义为:

typedef unsigned int uip_stats_t;

它们已被记录并呈现给我如下:

    PRINTA("UIP STATS. recv %d sent %d drp %d\n",
        uip_stat.ip.recv,
        uip_stat.ip.sent,
        uip_stat.ip.drop);

我一直是上面代码打印的数字。

【问题讨论】:

  • “他们现在是负面的”——这是什么意思?你的意思是你将它们加载到int16_t变量或类似的东西吗?存储为 unsigned int 的值究竟是如何变成“负数”的? (提示:代码大声说话)。
  • unsigned ints 永远不应回绕为负数。见stackoverflow.com/q/18195715/3488231
  • 我不清楚,抱歉。希望我的编辑能让一切变得清晰。我怀疑打印代码可能有问题。
  • 在您的输出语句中,尝试使用%u 而不是%d。
  • 您的问题都在printf() - %d 是针对普通ints,而不是unsigned ints。请改用%u。

标签: c integer contiki


【解决方案1】:

在您的输出PRINTA() 语句中,您使用%d 作为格式说明符。

假设它是printf() 系列的一些包装器,%d 仅用于有符号整数(*);要输出无符号整数(*),您应该改用%u 说明符。

(*):在这种情况下,我指的是类型为int 和unsigned int(或等效)的变量。对于其他大小的整数类型,输出说明符不同。

为了证明这一点,请考虑以下示例:

int main() {
    int a;
    unsigned int b;
    a = -1;
    b = *(unsigned int *)&a;
    printf("%d %u\n", b, b);
    return 0;
}

在我的平台上输出:

-1 4294967295

要进一步了解这一点,您不妨阅读一下Two's complement。

【讨论】:

  • 严格来说,%d 仅适用于 int,包括等效类型 typeddefed 到 int,%u 也适用于 unsigned int 和等效类型。
  • 不幸的是,不是我的打印输出。但鉴于打印为 %d,实际值(将由 %u 打印)正如我所描述的那样,对吧?
  • @SvenAkkermans 不一定。如果 unsigned int 设置了最高有效位,printf() 会将其输出为负数,%d,但正数,%u。
  • @SvenAkkermans 我已经编辑了我的答案以展示我之前的评论。
猜你喜欢
  • 2018-08-18
  • 2012-02-21
  • 2023-02-01
  • 1970-01-01
  • 2011-04-26
  • 2017-06-07
  • 2011-01-04
  • 2021-10-04
相关资源
最近更新 更多