0

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_(...)
}
AnthonyR
  • 3,485
  • 1
  • 18
  • 41
user965972
  • 2,489
  • 2
  • 23
  • 39

2 Answers2

4

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.

You can test using the sizeof function:

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

Probably the easiest way to deal with this is 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 __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
}
2

There is a CGFLOAT_IS_DOUBLE macro defined in Core Graphics. You can use it in Swift for direct comparison:

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

Of course, direct size comparison is also possible:

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

However, since there are overloaded functions for all Float, Double and CGFloat, there is rarely a reason to inspect the size of the type.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • I was just editing my answer to use `CGFLOAT_IS_DOUBLE`. I didn't know about it until I was just poking around. Good call on using both sizes to direct compare. –  May 31 '16 at 13:02
  • @ColGraff Unfortunately it doesn't seem it is possible to use it in conditional compilation. We can check only that it's defined... which is always. – Sulthan May 31 '16 at 13:06
  • Ahh, yep. I thought there was a reason it couldn't be used like that. Too bad. –  May 31 '16 at 13:13