【问题标题】:Is there a difference between these two operations? [closed]这两种操作有区别吗? [关闭]
【发布时间】:2018-05-17 09:37:12
【问题描述】:

我想问一下结果(s16Result)之间是否有差异

int16_t s16X, s16Y, s16Result;

s16Result = (int16_t) (s16X - s16Y);

int16_t s16X, s16Y, s16Result;

s16Result = (int16_t) ((uint16_t) s16X - (uint16_t) s16Y)

s16X 和 s16Y 的数据类型为有符号整数,因此范围为 -32767...32767 。谢谢。

【问题讨论】:

  • 您应该能够轻松地制作一个测试程序,将其中一个值设为负值,然后查看两个操作的结果并进行比较。
  • @Someprogrammerdude:在一个 C 实现中测试一个程序中的一个样本并不能提供关于 C 标准一般要求的明确答案。
  • @EricPostpischil 不,但它应该给出一些提示。
  • @EricPostpischil 但仅一个示例表明它们不相等就足以说明它们不相等。现在会发生什么
  • @Someprogrammerdude:可能会也可能不会。一个示例最多提供一个可能的结果,而 C 标准可能允许多个可能的结果或无限多的结果(未定义的行为)。示例根本无法提供这些信息。

标签: c


【解决方案1】:

这些语句通常与 C 标准定义的行为不同。考虑何时s16X 具有其类型的最小值(例如,可能INT_MINint 类型为16 位的实现中,因此它可能是-32767)并且s16Y 为2。然后,在:

s16Result = (T_S16) (s16X - s16Y)

表达式s16X - s16Y 溢出——-32769 的数学结果无法在int 类型中表示,C 标准没有定义结果。

但是,在:

s16Result = (T_S16) ((T_U16) s16X - (T_U16) s16Y)

T_U16 类型可能是无符号的 16 位类型。在这种情况下,s16X 通过加减 65536 转换为 16 位类型,得到 32769。s16Y 保留其值 2。然后减法得到 32767。最后,此结果转换为 T_S16类型,保持值为 32767。

因此,在使用有符号算术的语句没有 C 标准定义的值的某些情况下,使用无符号算术的语句可能具有定义的值。

(如果最终结果不能以 T_S16 类型表示,则使用无符号算术的语句仍然具有未定义的行为,例如最终结果是从 32768 到 65535 而不是从 0 到 32767 的数字。)

【讨论】:

    猜你喜欢
    • 2020-02-14
    • 2010-11-03
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多