2011-10-08 9 views
11

TLDR: Come si chiama il codice a virgola mobile standard in un modo che compila sia CGFloats a 32 e 64 bit senza avvisi?CGFloat: round, floor, abs e precisione 32/64 bit


CGFloat è definito come double o float, a seconda delle impostazioni del compilatore e della piattaforma. Sto cercando di scrivere codice che funzioni bene in entrambe le situazioni, senza generare molti avvisi.

Quando utilizzo funzioni come floor, abs, ceil e altre semplici operazioni in virgola mobile, ricevo avvisi sui valori che vengono troncati. Per esempio:

avvertimento: conversione implicita accorcia valore a 64 bit in un valore a 32 bit

Io non sono preoccupato per la correttezza o la perdita di precisione nei calcoli, come mi rendo conto che ho potrei usare sempre le versioni a doppia precisione di tutte le funzioni per tutto il tempo (floor invece di floorf, ecc.); tuttavia, dovrei tollerare questi errori.

C'è un modo per scrivere codice in modo pulito che supporti i float sia a 32 bit che a 64 bit senza dover utilizzare molte funzioni di #ifdef __ LP64 __ o scrivere wrapper per tutte le funzioni standard a virgola mobile?

risposta

19

È possibile utilizzare queste funzioni da 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'. 
+1

Ora che so cosa cercare, ho trovato questa domanda: http://stackoverflow.com/questions/ 5352457/cgfloat-based-math-functions – leecbaker

+1

Nota che in Xcode 6.1, incluso tgmath non aiuta se i moduli sono abilitati. Vedi http://stackoverflow.com/q/23333287/449161 –

3

Se avete solo bisogno di un paio di funzioni è possibile utilizzare questo invece:

#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