Comment arrondir CGFloat
-
28-09-2019 - |
Question
j'ai fait cette méthode
+ (CGFloat) round: (CGFloat)f {
int a = f;
CGFloat b = a;
return b;
}
Cela fonctionne comme prévu mais cela ne fait qu'arrondir.Et si le nombre est négatif, il est toujours arrondi à l'inférieur.
C'était juste une méthode rapide que j'ai créée, il n'est pas très important qu'elle arrondisse correctement, je l'ai juste fait pour arrondir les valeurs x et y de la caméra pour mon jeu.
Cette méthode est-elle correcte ?Est-ce rapide ?Ou bien y a-t-il une meilleure solution?
La solution
Il existe déjà des fonctions standard avec les comportements que vous pourriez avoir besoin <math.h>
tels que: floorf
, ceilf
,
roundf
, rintf
et nearbyintf
(LASF 'f' signifie "flotter" la version, les versions sans ce sont des versions "double").
Il est préférable d'utiliser des méthodes standard non seulement parce qu'ils sont standard, mais parce qu'ils fonctionnent mieux dans les cas de pointe.
Mise à jour 2013 (jessedc)
iOS ne sont plus seulement 32 bits. Il y a un certain nombre d'autres réponses à cette question sont plus pertinents.
La plupart des réponses mentionnent l'importation tgmath.h
Autres conseils
Réponse 2018
Les autres réponses ici sont soit datées, soit ne donnent pas de bons exemples.Il est facile d'arrondir un CGFloat
en utilisant Swift intégré rounded
fonction.
let x: CGFloat = 3.5
let y = x.rounded() // 4.0
Si vous souhaitez arrondir la valeur en place, vous pouvez utiliser round
:
var x: CGFloat = 3.5
x.round() // 4.0
Règles d'arrondi
Si vous souhaitez un contrôle plus précis sur la manière dont les nombres sont arrondis, vous pouvez utiliser un FloatingPointRoundingRule
.
Loin de zéro
x.rounded(.awayFromZero)
Les nombres au-dessus de zéro sont arrondis vers le haut et les nombres en dessous de zéro sont arrondis vers le bas.
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
Vers le bas
x.rounded(.down)
Arrondit n’importe quel nombre avec une valeur décimale au nombre entier immédiatement inférieur.C'est la même chose que 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
Au plus près ou loin de zéro
x.rounded(.toNearestOrAwayFromZero) // same as x.rounded()
Les nombres décimaux sont arrondis à la valeur entière la plus proche.Cependant, lorsque la valeur est exactement au milieu (comme 3.5
ou -3.5
) puis les nombres positifs sont arrondis et les nombres négatifs sont arrondis à l'inférieur.
Son nom est peut-être long et compliqué, mais c'est normalement ainsi qu'on apprend l'arrondi à l'école.C'est aussi la règle utilisée si vous faites simplement 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
Au plus proche ou même
x.rounded(.toNearestOrEven)
Ceci est similaire à toNearestOrAwayFromZero
, sauf que maintenant le .5
les valeurs sont arrondies au nombre entier pair.
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 ***
Vers zéro
x.rounded(.towardZero)
Cela a simplement pour effet de supprimer toutes les valeurs décimales.Si vous aviez besoin d'un Int
tu pourrais faire la même chose avec 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
En haut
x.rounded(.up)
C'est le contraire de .down
.Tous les nombres décimaux sont arrondis.C'est la même chose que 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
Remarques
- N'oubliez pas de prendre en compte les valeurs négatives.
- Les résultats de
round
etrounded
sont encoreCGFloat
.Si vous avez besoin d'unInt
tu dois le convertir commeInt(myCGFloat)
. - Il n'est pas nécessaire d'utiliser les fonctions mathématiques C
round(x)
,ceil(x)
etfloor(x)
plus.Cependant, si vous les utilisez, ils gèrent à la fois les architectures 64 et 32 bits, donc toutes les réponses que vous avez pu voir avecroundf
,ceilf
etfloorf
sont désormais obsolètes.
A CGFloat
est-typedef soit un double
ou un float
, de sorte que vous pouvez les compléter comme tout autre type réel:
CGFloat round(CGFloat aFloat)
{
return (int)(aFloat + 0.5);
}
Notez que si cela fonctionne avec des flotteurs assez petit pour transporter une fraction, il peut agir bizarre sur de grandes valeurs.
Essayez #import "tgmath.h"
.
L'en-tête de <tgmath.h>
comprendra les en-têtes et <math.h>
<complex.h>
et définira plusieurs macros de type générique.
Vous réinventent la roue - et cela est une question C, non Objectif C. Il suffit d'utiliser la fonction ronde standard C ()
.Pour travailler avec 32 et 64 bits, vous pouvez créer vos propres de macro comme
#ifndef CGFLOAT_CEIL
#ifdef CGFLOAT_IS_DOUBLE
#define CGFLOAT_CEIL(value) ceil(value)
#else
#define CGFLOAT_CEIL(value) ceilf(value)
#endif
#endif
Ps ce n'est pas une réponse à la question, mais un ajout de la question sur la façon de travailler avec des valeurs de 32/64 bits.
Définir ceci dans un fichier comme MyMacros.h et que d'ajouter une importation dans le myapp-Prefix.pch
Rappelez-vous aussi que le choix CGFloat comme préfixe pour votre fonction peut être un risque puisque Apple pourrait ajouter une macro comme cela leur auto c'est pourquoi le #ifndef CGFLOAT_CEIL est