【问题标题】:unsigned short integer promotion in 32-bit system32 位系统中的无符号短整数提升
【发布时间】:2015-10-14 04:12:48
【问题描述】:

我有一个 32 位整数大小

如果我有类似的算术表达式

unsigned short current_time, last_time
if((current_time - last_time) > timeout)

我相信 current_time 和 last_time 在减法之前都会被转换为signed int 32。 16 位整数大小系统没有问题,但是使用这个 32 位整数大小系统是否会因为整数提升而产生负值?

【问题讨论】:

  • 添加语言标签,C、C++ 或 ?

标签: c integer-promotion


【解决方案1】:

如果current_time 大于或等于last_time,则不可能出现负值。

引用 C90 规范的第 6.2.1.2 节“有符号和无符号整数”:

当一个整数类型的值转换为另一个整数类型时,如果该值可以用新类型表示,则其值不变。

由于unsigned shortint 短,所有unsigned short 类型的值都可以用int 表示,因此current_timelast_time 转换为int 的值将是与它们未转换的 unsigned short 值相同,减法的结果将是您期望的结果。

但是,如果current_time 小于 last_time,则可能出现负值;然而,这不是一个错误,而是一个特性,因为在这种情况下,时间真的确实倒退了。

如果current_timelast_timeunsigned ints,并且current_time 小于last_time,则减法的结果将是unsigned int,因此不是负数;这将是时间之间的差异,以unsigned int 的最大值为模。

无论如何,如果可能发生的话,您可能想特别处理时间倒退。

【讨论】:

  • 我不知道单位,但我的猜测是 16 位时间可能会经常溢出。如果是这样,那么我还怀疑最好的办法是将时间视为循环并改用(unsigned short) ((unsigned int) current_time - last_time) < timeout,从而在有限的框架内正确比较时间值。或者,如果可能出现负数,并为健全的二进制补码环境编译,则可以使用强制转换为有符号短。
【解决方案2】:

根据现代 C 规则,无符号短裤将提升为有符号整数,并且将根据其原始值正确签名。

【讨论】:

  • 提升会发生在减法的每个变量上还是只发生在结果上?如果提升发生在减法之前的每个变量上,是否有可能在减法之后得到负值?也许当16位值当前时间溢出回0并且最后一次是65000+?
  • 是的,如果 16 位值溢出并变小,则提升将保留该小值,并且减法将返回否定结果。在这种情况下,提升不是你的问题——首先使用 unsigned short 是。如果您想避免这种情况,您必须将每个值单独转换为无符号整数。在这种情况下,您会得到看似没有问题但可能不正确的值。
猜你喜欢
  • 2014-10-03
  • 2016-05-08
  • 2011-01-31
  • 2012-07-27
  • 2011-06-02
  • 1970-01-01
  • 2019-05-21
  • 2017-07-01
  • 2015-07-28
相关资源
最近更新 更多