【问题标题】:integer promotion and unsigned interpretation整数提升和无符号解释
【发布时间】:2016-12-04 06:03:43
【问题描述】:
int_8 int8     = ~0;
uint_16 uInt16 = (uint_16) int8;

关于上面的类型转换;在 C 标准中,我可以在哪里找到对以下行为指示的参考? - 在无符号解释 (uInt16=0xFFFF) 之前对较大类型进行符号扩展,而不是在无符号解释之后对较大类型进行 0 扩展 (uInt16=0xFF)。

从 C99 6.3.1.8

否则,如果无符号整数类型的操作数的秩大于或等于另一个操作数类型的秩,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型输入。

上面的声明很清楚需要转换哪个变量,但是关于实际上应该如何执行对话并不是很清楚,因此我的问题是要求从标准中获得参考。 谢谢

【问题讨论】:

  • 经验法则:(uint_16)int8 + (uint_16)(-int8) == 0 应该成立。
  • @lorro 不同意(uint_16)int8 + (uint_16)(-int8) == 0。使用int_8,uint_16 作为int8_t, uint16_t,在32 位int 机器上,使用int8 > 0,结果始终为65536,类型为int
  • @chux:是的,抱歉,忘记了最后的演员表。修复:(uint16_t)( (uint16_t)int8 + (uint16_t)(-int8)) == 0。感谢您发现!

标签: c casting integer-promotion


【解决方案1】:

根据standard

6.3.1.3 有符号和无符号整数

......
2.否则,如果新类型是无符号的,则在新类型所能表示的最大值的基础上反复加减1,直到值在新类型的范围内。

以及在解释上述内容时避免混淆的脚注:

这些规则描述的是数学值的算术运算,而不是给定类型表达式的值。

即如果您的 int8 的值为 -1 (假设负数表示是 2 的补码,在您的示例中也是如此),当转换为 uint16_t 时,值 (0xFFFF + 1) 将被添加到它(比uint16_t) 可以表示的最大值,产生0xFFFF + 1 - 1 = 0xFFFF 的结果。

【讨论】:

  • 感谢您的回答,但我不是我正在寻找的答案,因为无符号转换可能发生在零/符号扩展之前。即最大值+1可以在零扩展之前添加到int8,给出0xFF,而不是在符号扩展之后将最大值+1添加到int16,产生0xFFFF。
  • 如果您查看链接中的脚注,提供的内容是:规则描述的是数学值的算术运算,而不是给定类型表达式的值。。所以没有符号扩展的概念或任何相关的概念,因为我们正在谈论纯算术(将其添加到答案中)。
【解决方案2】:

我认为答案实际上也是 6.3.1.8 的一部分:

否则,整数提升将在两个操作数上执行。 那么以下规则将应用于提升的操作数: …… 否则,如果具有无符号整数类型的操作数的排名大于或等于另一个操作数的类型的排名.....

意味着在使用规则 6.3.1.3 转换为无符号之前首先执行整数提升。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 2022-01-20
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多