【问题标题】:taking absolute value of CGFloat取 CGFloat 的绝对值
【发布时间】:2013-01-16 01:08:43
【问题描述】:

我该怎么做?我尝试了 abs() 但它只适用于 int。有内置的方法吗?

CGFloat flo = -123;
abs(flo)

返回 0

【问题讨论】:

  • 标准 'abs' 函数在 Swift 4 中效果很好

标签: iphone ios objective-c ipad


【解决方案1】:

使用 fabs()

CGFloat f = -123.4f;
CGFloat g = fabs(f);

CGFloat 在 64 位机器上定义为 double,在 32 位机器上定义为 float。如果您同时针对 64 位和 32 位,则此答案会变得更复杂,但仍然正确。

您想使用fabs(),因为它适用于大于floatdouble 数据类型。在 32 位上,仅当您采用 CGFloat 的绝对值或float。如果您尝试存储大 double 数字的绝对值,您可能会溢出 32 位 CGFloat。简而言之,64 位就可以了,在 32 位上不要混用 doubleCGFloat 就可以了。

ABS() 宏显然会对某些编译器产生副作用。

【讨论】:

  • 正确 (+1),但打印值或进行分配。
  • CGFloat 是浮点型或双精度型(32/64 位系统)的类型定义。 fabs 需要双倍(至少在我的 xcode 中,这就是它想要的)。那么这样会安全吗?
  • 由于 CGFloat 可以定义为双精度或浮点数,因此很难说这是正确的答案:fabsf 期望浮点数作为输入参数,fabs 总是返回双精度数。建议在 32 位/64 位环境(如今天的手机)中使用 std::abs() 或宏 ABS()。
  • 这在 64 位 iOS 中不再正确,您会收到语义问题警告:Absolute value function 'fabsf' given an argument of type 'CGFloat' (aka 'double') but has parameter of type 'float' which may cause truncation of value
  • 您能否扩展您关于ABS() 对某些编译器有副作用的最后评论?哪些编译器?如果我坚持使用 Xcode,它是否完全安全?
【解决方案2】:

对于 64/32 位系统

#if CGFLOAT_IS_DOUBLE
    CGFloat g = fabs(flo);
#else
    CGFloat g = fabsf(flo);
#endif

【讨论】:

  • 这是最好的答案,而不是制作自己的宏包装器。除此之外,请确定您是否真的需要担心任何 32 位平台。
  • 这正是 Skela 在另一个答案中所说的预定义宏 ABS 的用途。
【解决方案3】:

据我所知,我通常只使用 ABS 宏,无论您使用哪个系统或使用哪个原语,它都可以工作。

CGFloat x = -1.1;
double y = -2.1;
NSInteger z = -5;

x = ABS(x);
y = ABS(y);
z = ABS(z);

【讨论】:

    【解决方案4】:

    小补充:

    CGFloat g = fabs(f);
    

    这将导致强制转换警告,因为 fabs() 返回一个双精度值。 要返回浮点值,您需要使用 fabsf()。

    CGFloat g = fabsf(f);
    

    【讨论】:

      【解决方案5】:

      fabs 已折旧。 abs 的签名现在与此签名通用

      /// Returns the absolute value of the given number.
      ///
      /// The absolute value of `x` must be representable in the same type. In
      /// particular, the absolute value of a signed, fixed-width integer type's
      /// minimum cannot be represented.
      ///
      ///     let x = Int8.min
      ///     // x == -128
      ///     let y = abs(x)
      ///     // Overflow error
      ///
      /// - Parameter x: A signed number.
      /// - Returns: The absolute value of `x`.
      @inlinable public func abs<T>(_ x: T) -> T where T : Comparable, T : SignedNumeric
      

      【讨论】:

        猜你喜欢
        • 2020-03-20
        • 2019-04-27
        • 2018-04-18
        • 1970-01-01
        • 2021-05-03
        • 1970-01-01
        • 1970-01-01
        • 2021-05-25
        • 1970-01-01
        相关资源
        最近更新 更多