取 CGFloat 的绝对值

Posted

技术标签:

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

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

CGFloat flo = -123;
abs(flo)

返回 0

【问题讨论】:

标准 'abs' 函数在 Swift 4 中效果很好 【参考方案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

【讨论】:

以上是关于取 CGFloat 的绝对值的主要内容,如果未能解决你的问题,请参考以下文章

在Shell中怎样对一个变量取绝对值

awk判断整除,取绝对值,按位分割

python 浮点数取绝对值

Verilog 取绝对值

sqlserver取绝对值的abs()函数

Math.abs()方法 取绝对值