CGFloat: раунд, пол, абс и точность 32/64 бит

TL;DR: как я могу назвать стандартный код с плавающей запятой способом, который компилирует 32-х и 64-разрядные CGFloats без предупреждений?


CGFloat определяется как double или float, в зависимости от настроек компилятора и платформы. Я пытаюсь написать код, который хорошо работает в обеих ситуациях, не генерируя много предупреждений.

Когда я использую такие функции, как floor, abs, ceil и другие простые операции с плавающей запятой, я получаю предупреждения об усеченных значениях. Например:

предупреждение: неявное преобразование сокращает 64-битное значение до 32-битного значения

Меня не интересуют правильность или потеря точности вычислений, поскольку я понимаю, что я мог бы просто использовать версии с двойной точностью всех функций все время (пол вместо floorf и т.д.); однако я должен был бы терпеть эти ошибки.

Есть ли способ написать код, который поддерживает как 32-битные, так и 64-битные поплавки без необходимости использовать много файлов #ifdef __ LP64 __ или писать функции-обертки для всех стандартных функций с плавающей запятой?

Ответ 1

Вы можете использовать эти функции из tgmath.h.

#include <tgmath.h>

...

double d = 1.5;
double e = floor(d);   // will choose the 64-bit version of 'floor'

float f = 1.5f;
float g = floor(f);    // will choose the 32-bit version of 'floorf'.

Ответ 2

Если вам нужны только несколько функций, вы можете использовать это вместо:

#if CGFLOAT_IS_DOUBLE
#define roundCGFloat(x) round(x)
#define floorCGFloat(x) floor(x)
#define ceilCGFloat(x) ceil(x)
#else
#define roundCGFloat(x) roundf(x)
#define floorCGFloat(x) floorf(x)
#define ceilCGFloat(x) ceilf(x)
#endif