0

Кварц использует для своей графики CGFloat. CGFloat - либо Float, либо Double, в зависимости от процессора.Как определить, является ли CGFloat Float или Double

Ускоренный каркас имеет различные варианты одной и той же функции. Например, dgetrf_ для Double и sgetrf_ для Float's.

Я должен сделать эти две работы вместе. Либо я могу использовать Double везде и конвертировать их в CGFloat каждый раз, когда я использую кварц, или я могу (попытаться) определить фактический тип CGFloat и использовать соответствующую функцию ускорения.

Смешивание CGFloat's и Double типов по всей моей базе кода не очень привлекательно и конвертирует тысячи или миллионы значений в CGFloat, каждый раз не поражает меня как очень эффективный.

В этот момент я бы пошел со вторым вариантом. (Или не должен?)

Мой вопрос: как узнать фактический тип CGFloat?

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

ответ

4

Documentation on Swift Floating-Point Numbers:

Типы с плавающей точкой могут представлять собой гораздо более широкий диапазон значений, чем целочисленных типов, и может хранить числа, которые намного больше или меньше , чем могут быть сохранены в Int. Swift предоставляет два типа с плавающей запятой :

  • Двойной представляет собой 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

Вы можете просто проверить \ __ LP64 \ __ здесь вместо x86_64 + arm64. –

+0

Спасибо, я добавлю это к ответу. – ColGraff

2

Существует макрос CGFLOAT_IS_DOUBLE, определенный в Core Graphics. Вы можете использовать его в Swift для прямого сравнения:

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

Конечно, прямое сравнение размеров также возможно:

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

Однако, поскольку перегружены функции для всех Float, Double и CGFloat, там редко является причиной для проверки размера этого типа.

+0

Я просто редактировал свой ответ, чтобы использовать 'CGFLOAT_IS_DOUBLE'. Я не знал об этом, пока я просто не зашумел. Хороший призыв использовать оба размера для прямого сравнения. – ColGraff

+0

@ColGraff К сожалению, это не представляется возможным использовать в условной компиляции.Мы можем проверить только, что он определен ... который всегда. – Sulthan

+0

Ах, да. Я думал, что есть причина, по которой он не может быть использован так. Очень жаль. – ColGraff

Смежные вопросы