如何确定CGFloat是Float还是Double

时间:2016-05-31 12:10:06

标签: swift quartz-graphics quartz-core accelerate-framework cgfloat

Quartz使用CGFloat作为其图形。 CGFloat可以是FloatDouble,具体取决于处理器。

Accelerate框架具有相同功能的不同变体。 例如,对于Double的dgetrf_和对于Float的sgetrf_。

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

在我的代码库中混合使用CGFloat'sDouble类型不是很吸引人,每次将数千或数百万个值转换为CGFloat也不会让我觉得非常有效。

此刻我会选择第二种选择。 (或者不应该?)

我的问题是:如何知道CGFloat的实际类型?

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

2 个答案:

答案 0 :(得分:4)

Documentation on Swift Floating-Point Numbers:

  

浮点类型可以表示比其更广泛的值   整数类型,可以存储更大或更小的数字   可以存储在Int中。 Swift提供了两个带符号的浮点数   数字类型:

     
      
  • Double表示64位浮点数。
  •   
  • Float表示32位浮点数。
  •   

您可以使用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
}

答案 1 :(得分:2)

Core Graphics中定义了CGFLOAT_IS_DOUBLE宏。您可以在Swift中使用它进行直接比较:

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

当然,也可以直接进行尺寸比较:

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

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