【问题标题】:How does C handle sign extension?C如何处理符号扩展?
【发布时间】:2012-10-21 15:57:24
【问题描述】:

我有一个指向字节缓冲区的指针,我从中将每个偶数索引字节复制到一个 int(由于数据存储到缓冲区的协议,我知道奇数周期用于读取)。 现在当我这样做时

signed int a;
...
//inside a loop
a = buffer[2*i]; //buffer is unsigned

它给了我一个无符号数。但是当我这样做时

a = (int8_t)buffer[2*i]

号码以签名形式显示。这迫使我重新思考 c 中的符号扩展是如何工作的,尤其是在上述情况下。 我的理解是,因为我声明了一个已签名的,编译器会自动进行符号扩展。任何人都可以花一些时间来解释为什么不是这样。我只是在这个陷阱里呆了一个小时,不想以后再落入同样的陷阱。

【问题讨论】:

  • 我知道符号扩展在 C 中是如何工作的,但是如果您有一个无符号数(但“符号位”为 1)并且您通过转换为更长的整数来进行符号扩展,那是怎么回事处理?抱歉,如果问题不清楚。

标签: c unsigned signed


【解决方案1】:

buffer 是一个无符号八位整数数组(或作为一个整数)。所以buffer[2*i]的值在0到255(含)的范围内,该范围内的所有值都可以表示为ints,所以赋值

a = buffer[2*i];

保留值,提升到更广泛的类型int 是通过用零填充来完成的。

如果您在分配之前转换为int8_t

a = (int8_t)buffer[2*i]

缓冲区中大于 127 的值以实现定义的方式转换为类型 int8_t,很可能只是将位模式重新解释为带符号的 8 位整数,这会导致负值,来自 - 128 到 -1。这些值可以表示为ints,因此它们会保留在赋值中,然后通过符号扩展将值保留提升为更广泛的类型int

【讨论】:

    【解决方案2】:

    一个 int_8 只有 8 位,如果最高位是 1,它持有一个负值: 1xxxxxxx ,如果你将这样的值分配给一个有符号的 int(32 或 64 位),你当然会得到一个负值。分配后较长的 int 看起来像 11111111 11111111 11111111 1xxxxxxx,只需一个简单的 xor 就可以达到 00000000 ^ 1001 => 11111001 的效果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-16
      • 1970-01-01
      • 2011-07-08
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多