【问题标题】:How to determine if CGFloat is Float or Double [duplicate]如何确定 CGFloat 是 Fl​​oat 还是 Double [重复]
【发布时间】:2016-05-31 12:10:05
【问题描述】:

Quartz 的图形使用CGFloatCGFloatFloatDouble,具体取决于处理器。

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

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

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

    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
    }
    

    【讨论】:

    • 你可以在这里测试 _LP64_ 而不是 x86_64 + arm64。
    • 谢谢,我会把它添加到答案中。
    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 我只是在编辑我的答案以使用CGFLOAT_IS_DOUBLE。直到我四处闲逛,我才知道这件事。很好地呼吁使用两种尺寸进行直接比较。
    • @ColGraff 不幸的是,似乎不可能在条件编译中使用它。我们只能检查它是否已定义...始终如此。
    • 啊,是的。我认为它不能像那样使用是有原因的。太糟糕了。
    猜你喜欢
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多