Come arrotondare CGFloat
-
28-09-2019 - |
Domanda
Ho realizzato questo metodo
+ (CGFloat) round: (CGFloat)f {
int a = f;
CGFloat b = a;
return b;
}
Funziona come previsto ma arrotonda solo per difetto.E se è un numero negativo viene comunque arrotondato per difetto.
Questo è stato solo un metodo rapido che ho creato, non è molto importante che venga arrotondato correttamente, l'ho semplicemente fatto per arrotondare i valori xey della fotocamera per il mio gioco.
Questo metodo va bene?È veloce?Oppure esiste una soluzione migliore?
Soluzione
Ci sono già le funzioni standard con comportamenti potrebbe essere necessario in <math.h>
quali: floorf
, ceilf
,
roundf
, rintf
e nearbyintf
(mezzi lasf 'F' la versione "galleggiare", le versioni senza di essa sono le versioni "doppi").
E 'meglio usare metodi standard non solo perché sono standard, ma perché lavorano meglio in casi limite.
2013 Update (jessedc)
iOS non è più solo a 32 bit. Ci sono una serie di altre risposte a questa domanda, che ora sono più pertinenti.
La maggior parte delle risposte ma va specificato importazione tgmath.h
Altri suggerimenti
Risposta del 2018
Le altre risposte qui sono datate o non forniscono buoni esempi.È facile arrotondare a CGFloat
utilizzando il built-in di Swift rounded
funzione.
let x: CGFloat = 3.5
let y = x.rounded() // 4.0
Se vuoi arrotondare il valore in atto puoi usare round
:
var x: CGFloat = 3.5
x.round() // 4.0
Regole di arrotondamento
Se desideri un controllo più preciso sul modo in cui i numeri vengono arrotondati, puoi utilizzare a FloatingPointRoundingRule
.
Lontano dallo zero
x.rounded(.awayFromZero)
I numeri sopra lo zero vengono arrotondati per eccesso mentre i numeri sotto lo zero vengono arrotondati per difetto.
3.000 -> 3.0
3.001 -> 4.0
3.499 -> 4.0
3.500 -> 4.0
3.999 -> 4.0
-3.000 -> -3.0
-3.001 -> -4.0
-3.499 -> -4.0
-3.500 -> -4.0
-3.999 -> -4.0
Giù
x.rounded(.down)
Arrotonda qualsiasi numero con un valore decimale al numero intero successivo più piccolo.Questo è lo stesso di floor(x)
.
3.000 -> 3.0
3.001 -> 3.0
3.499 -> 3.0
3.500 -> 3.0
3.999 -> 3.0
-3.000 -> -3.0
-3.001 -> -4.0
-3.499 -> -4.0
-3.500 -> -4.0
-3.999 -> -4.0
Al più vicino o lontano dallo zero
x.rounded(.toNearestOrAwayFromZero) // same as x.rounded()
I numeri decimali vengono arrotondati al valore intero più vicino.Tuttavia, quando il valore è esattamente nel mezzo (come 3.5
O -3.5
) quindi i numeri positivi vengono arrotondati per eccesso e quelli negativi per difetto.
Può avere un nome lungo e complicato, ma normalmente è così che si impara ad arrotondare a scuola.È anche la regola utilizzata se lo fai e basta x.rounded()
.
3.000 -> 3.0
3.001 -> 3.0
3.499 -> 3.0
3.500 -> 4.0 ***
3.999 -> 4.0
-3.000 -> -3.0
-3.001 -> -3.0
-3.499 -> -3.0
-3.500 -> -4.0 ***
-3.999 -> -4.0
Al più vicino o addirittura
x.rounded(.toNearestOrEven)
Questo è simile a toNearestOrAwayFromZero
, tranne ora il .5
i valori vengono arrotondati al numero intero pari.
3.000 -> 3.0
3.001 -> 3.0
3.499 -> 3.0
3.500 -> 4.0 ***
3.999 -> 4.0
4.500 -> 4.0 ***
-3.000 -> -3.0
-3.001 -> -3.0
-3.499 -> -3.0
-3.500 -> -4.0 ***
-3.999 -> -4.0
-4.500 -> -4.0 ***
Verso lo zero
x.rounded(.towardZero)
Questo ha semplicemente l'effetto di tagliare qualsiasi valore decimale.Se avessi bisogno di un Int
potresti fare la stessa cosa con Int(x)
.
3.000 -> 3.0
3.001 -> 3.0
3.499 -> 3.0
3.500 -> 3.0
3.999 -> 3.0
-3.000 -> -3.0
-3.001 -> -3.0
-3.499 -> -3.0
-3.500 -> -3.0
-3.999 -> -3.0
Su
x.rounded(.up)
Questo è l'opposto di .down
.Tutti i numeri decimali vengono arrotondati per eccesso.Questo è lo stesso di ceil(x)
.
3.000 -> 3.0
3.001 -> 4.0
3.499 -> 4.0
3.500 -> 4.0
3.999 -> 4.0
-3.000 -> -3.0
-3.001 -> -3.0
-3.499 -> -3.0
-3.500 -> -3.0
-3.999 -> -3.0
Appunti
- Non dimenticare di prendere in considerazione i valori negativi.
- I risultati di
round
Erounded
sono ancoraCGFloat
.Se hai bisogno di unInt
devi convertirlo comeInt(myCGFloat)
. - Non è necessario utilizzare le funzioni matematiche del C
round(x)
,ceil(x)
Efloor(x)
più.Tuttavia, se li usi, gestiscono sia l'architettura a 64 che a 32 bit, quindi qualsiasi risposta che potresti aver visto conroundf
,ceilf
Efloorf
sono ormai obsoleti.
Un CGFloat
IS typedef, o un double
o un float
, in modo da poterli arrotondare come qualsiasi altro tipo reale:
CGFloat round(CGFloat aFloat)
{
return (int)(aFloat + 0.5);
}
Si noti che se questo funziona con carri allegorici piccolo abbastanza per portare una frazione, si può agire strano su valori di grandi dimensioni.
Prova #import "tgmath.h"
.
L'intestazione <tgmath.h>
includerà la <math.h>
intestazioni e <complex.h>
e definirà diverse macro-tipo generico.
Si reinventare la ruota - e questa è una domanda C, non Objective C. Basta usare la funzione standard C round ()
.Per lavorare con 32 e 64 bit è possibile creare le proprie macro di come
#ifndef CGFLOAT_CEIL
#ifdef CGFLOAT_IS_DOUBLE
#define CGFLOAT_CEIL(value) ceil(value)
#else
#define CGFLOAT_CEIL(value) ceilf(value)
#endif
#endif
Ps questa non è una risposta per la domanda, ma un complemento per la domanda su come il lavoro con i valori di 32/64 bit.
Definire questo in un file, come MyMacros.h e che aggiungere un import in myapp-Prefix.pch
Si ricorda inoltre che la scelta di CGFloat come prefisso per la funzione può essere un rischio in quanto Apple potrebbe aggiungere una macro come questo loro auto in modo tale che è il motivo per il #ifndef CGFLOAT_CEIL è