如何确定 CGFloat 是 Fl​​oat 还是 Double

How to determine if CGFloat is Float or Double

Quartz 使用 CGFloat 作为其图形。 CGFloatFloatDouble,具体取决于处理器。

Accelerate 框架具有相同功能的不同变体。 例如 dgetrf_ 用于 Double's 和 sgetrf_ 用于 Float's.

我必须让这两个一起工作。我可以在任何地方使用 Double 并在每次使用石英时将它们转换为 CGFloat,或者我可以(尝试)确定 CGFloat 的实际类型并使用适当的 Accelerate 函数。

在我的代码库中混合使用 CGFloat'sDouble 类型不是很吸引人,并且每次都将数千或数百万个值转换为 CGFloat 也不是很高效。

此时我会选择第二个选项。 (或者我不应该?)

我的问题是:我怎么知道 CGFloat 的实际类型?

if ??? //pseudo-code: CGFloat is Double
{
   dgetrf_(...)
}
else
{
   sgetrf_(...)
}

Documentation on Swift Floating-Point Numbers:

Floating-point types can represent a much wider range of values than integer types, and can store numbers that are much larger or smaller than can be stored in an Int. Swift provides two signed floating-point number types:

  • Double represents a 64-bit floating-point number.
  • Float represents a 32-bit floating-point number.

您可以使用 sizeof 函数进行测试:

if sizeof(CGFloat) == sizeof(Double) {
  // CGFloat is a Double
} else {
  // CGFloat is a Float
}

可能最简单的处理方法是使用条件编译来定义一个包装器,它将调用正确的版本:

import Accelerate

func getrf_(__m: UnsafeMutablePointer<__CLPK_integer>,
            __n: UnsafeMutablePointer<__CLPK_integer>,
            __a: UnsafeMutablePointer<CGFloat>,
            __lda: UnsafeMutablePointer<__CLPK_integer>,
            __ipiv: UnsafeMutablePointer<__CLPK_integer>,
            __info: UnsafeMutablePointer<__CLPK_integer>) -> Int32 {

  #if __LP64__ // CGFloat is Double on 64 bit archetecture
    return dgetrf_(__m, __n, UnsafeMutablePointer<__CLPK_doublereal>(__a), __lda, __ipiv, __info)
  #else
    return sgetrf_(__m, __n, UnsafeMutablePointer<__CLPK_real>(__a), __lda, __ipiv, __info)
  #endif
}

Core Graphics 中定义了一个 CGFLOAT_IS_DOUBLE 宏。你可以在Swift中使用它来直接比较:

if CGFLOAT_IS_DOUBLE == 1 {
   print("Double") 
} else {
   print("Float")
}

当然也可以直接比较大小:

if sizeof(CGFloat) == sizeof(Double) {            
}

但是,由于所有 FloatDoubleCGFloat 都有重载函数,因此很少有理由检查类型的大小。