user965972 user965972 - 6 months ago 25
Swift Question

How to determine if CGFloat is Float or Double

Quartz uses CGFloat for its graphics. CGFloat is either Float or Double, depending on the processor.

The Accelerate framework has different variations of the same function.
For example dgetrf_ for Double's and sgetrf_ for Float's.

I have to make these two work together. Either I can use Double's everywhere and convert them to CGFloat every time I use quartz, or I can (try to) determine the actual type of CGFloat and use the appropriate Accelerate function.

Mixing CGFloat's and Double types all over my code base is not very appealing and converting thousands or millions of values to CGFloat every time doesn't strike me as very efficient either.

At this moment I would go with the second option. (Or shouldn't I?)

My question is: how do I know the actual type of CGFloat?

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

Answer

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.

Your can test using the sizeof function:

if sizeof(CGFloat) == 4 { // 4 bytes = 32 bits
  // CGFloat is a Float
} else {
  // CGFloat is a Double
}

The easiest way to deal with this might be to use conditional compilation to define a wrapper which will call the proper version:

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 arch(x86_64) || arch(arm64) // 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
}
Comments