【问题标题】:iphone: floats cast to unsigned ints get set to 0 if they are negative?iphone:如果浮点数为负数,则转换为无符号整数的浮点数设置为0?
【发布时间】:2011-01-30 05:47:48
【问题描述】:

试试看:

volatile float bob = -344.0f;
unsigned int fred = (unsigned int)bob;

printf("%d\n",fred);

输出将为 0。

显然,我希望它能够环绕,就像我从一个有符号的 int 转换为一个无符号的 int 一样(它确实在 iphone 上按预期进行环绕和运行)

我们假设它与浮点设置有关。

有什么想法吗?

【问题讨论】:

  • @KennyTM:一些随机尝试阻止它优化内容。
  • 旧线程,但我最近碰到了一些关于此的更多细节。在 XCode 7.2.x 中,将负浮点数转换为无符号短整数会在所有测试的 iOS 平台上产生一个环绕值。但是,对于 XCode 7.3.1,相同的代码会在 iPad 3 上导致截断为零并在 iPhone 6 上回绕。

标签: c iphone casting floating-point type-conversion


【解决方案1】:

这是意料之中的 - 将负浮点数转换为无符号整数会导致未定义的行为 (UB)。如果您希望值环绕(也是 UB,BTW),那么您需要先转换为(有符号的)int,然后再转换为无符号的 int。理想情况下,您根本不应该依赖 UB,而是找到一种更好的方法来做您需要做的事情。

【讨论】:

  • 那么为什么 VC++ 或 PSP 编译器没有问题?
  • @matt:因为你依赖于未定义的行为
  • @matt:如果您期望 int 为 0,那么这些编译器是一个问题,这与期望它环绕一样合理。这就是未定义行为的问题:你不能合理地期望任何特定的事情会发生。它可以环绕,它可以归零,它可以向你的雇主发送暗示性电子邮件——它完全不确定它会做什么。
  • @matt,仅仅因为有一个直观的结果并不意味着行为是由标准定义的。特别是,“显而易见的”转换实际上与从有符号整数类型中的相同值进行的转换完全不同,因此我们当然可以看到为什么实现可能更喜欢返回 0 而不是不可移植且可能令人困惑的结果。无论哪种方式,它都是合理和符合的,但有一种方式,它也是不一致的,而不是简单地未实现。
【解决方案2】:

通过有符号整数进行转换。

【讨论】:

    【解决方案3】:

    C 标准第 6.3.1.4 节:

    当一个有限值的实数浮动 类型转换为整数类型 _Bool 以外的小数部分 被丢弃(即,值为 向零截断)。如果值 不可分割的部分 由整数类型表示,则 行为未定义。

    就像 Paul R 所说,这是未定义的行为。

    【讨论】:

      【解决方案4】:

      此转换未定义,因此不可移植。

      根据 C99 §6.3.1.4 脚注 50:

      将整数类型的值转换为无符号类型时执行的求余运算不需要在将实浮点类型的值转换为无符号类型时执行。因此,可移植实浮点值的范围是(-1,Utype_MAX+1)。

      鉴于已知此转换不可移植,因此返回 0 而不是随机的特定转换是相当合理的解释。这至少有两个原因:(1) 标记不可移植代码而不是传播它,(2) 仅删除符号与转换整数类型的相同值时发生的情况大不相同,所以它是不清楚是否有任何特定的替代方案是更好的主意。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多