Comment faire pour arrondir des nombres à virgule flottante à l'entier le plus proche en C?
Est-il un moyen pour arrondir des nombres à C?
Je ne veux pas utiliser plafond et le plancher. Est-il une autre alternative?
Je suis tombé sur cet extrait de code lorsque j'ai Googlé pour la réponse:
(int)(num < 0 ? (num - 0.5) : (num + 0.5))
La ligne ci-dessus permet d'imprimer la valeur 4, même lorsque le flotteur num =4.9.
- Il ya beaucoup de différents types de l'arrondissement dont l'une(s) voulez-vous utiliser? S'il vous plaît poster des exemples de comportement souhaité.
- Je pense que le problème est ailleurs, il conviendrait sans doute d'impression 5 pour l'entrée de 4.9.
- Oui, la conversion d'un type à virgule flottante d'un type entier, qui peut représenter un nombre nécessaires de ce paramètre et de l'ampleur devrait fonctionner simplement en tronquant les décimales, ce code ne l' ±0,5 à cause de cette troncature à tour la valeur d'origine à l'écart à partir de zéro.
- Besoins
homework
tag ? - Quel est le problème avec
ceil
etfloor
? Aussi, voir stackoverflow.com/questions/485525/round-for-float-in-c. - voir stackoverflow.com/questions/2205211/... sauf pour remplacer
static_cast<int>
avec(int)
- La ligne ci-dessus n'a pas d'imprimer quoi que ce soit. Il n'y a rien dans cette ligne que peut faire aucune impression. Montrez-nous comment vous imprimer des choses. Le problème est sans doute là.
- Sous-ensemble: spécifique pour la division entière: stackoverflow.com/questions/2422712/... | C++ stackoverflow.com/questions/485525/round-for-float-in-c
Vous devez vous connecter pour publier un commentaire.
De 4,9 + 0,5 est 5.4, qui ne peut pas rond à 4, sauf si votre compilateur est brisé.
Je vient de confirmer que le Googlé code donne la bonne réponse pour 4.9.
a ? b : c
évalue àb
sia
est vrai et àc
autrement. Dans ce cas, l'idée est de déplacer la valeur denum
à l'écart à partir de zéro par0.5
avant la conversion de int en tronquant les décimales. De cette façon, la troncature rond le plus proche int (par exemple 0.5 + 0.5 = 1.0 et 0,99 + 0.5 = 1.49 deux tronquée à 1).float num = 5.0
et être fait avec elle.num
est en dehors de la plage deint
2), Il allait échouer pour de nombreuses autresfloat
sauf qu'il utilisedouble
mathématiques. par exemple,(int)(num < 0 ? (num - 0.5f) : (num + 0.5f))
a beaucoup de défaut des valeurs lors de l'num + 0.5f
tours pour unefloat
résultat.int
gamme,float
ne peut pas distinguer entre les nombres entiers et les fractions de toute façon. Avecdouble
, vous pouvez lancer àint64_t
.int
. Assez commun dans incorporé prédécesseurs en 2016.int
32-bits.int32_t
. OP code est bien surint
, pasint32_t
et amis. D'où mes commentaires concernantint
et une limitation(int)(num < 0 ? (num - 0.5) : (num + 0.5));
.Une solution générale est d'utiliser rint() et définir la FLT_ROUNDS mode d'arrondi selon le cas.
Je ne suis pas sûr que ce soit une bonne idée. Ce code dépend de jette, et je suis assez sûr que la troncature n'est pas défini.
Je dirais que c'est beaucoup mieux (ce qui est essentiellement ce Shiroko posté), car il ne dépend pas de les plâtres.
Pour arrondir un
float
en C, il y a 3<math.h>
fonctions pour répondre à ce besoin. Recommanderrintf()
.ou
ou
Exemple
Sortie
Ce qui est faible sur les OP de code?
Devrait
num
ont pas une valeur proche de laint
gamme, le casting(int)
résultats dans un comportement indéfini.Quand
num +/- 0.5
résultats dans une réponse inexacte. Il est peu probable ici que0.5
est undouble
causant le plus de se produire à un degré de précision plus élevé quefloat
. Lorsquenum
et0.5
ont la même précision, ajoutant0.5
à un nombre peut entraîner numérique arrondie réponse. (Ce n'est pas le nombre entier arrondi de l'OP post.) Exemple: le nombre juste moins de 0,5 doit arrondir à 0 par l'OP de l'objectif, encorenum + 0.5
résultats dans une réponse exacte entre la 1.0 et la plus petitedouble
un peu moins de 1,0. Depuis la réponse exacte n'est pas représentable, que la somme des tours, généralement à 1,0 conduisant à une réponse incorrecte. Une situation similaire se produit avec les grands nombres.OP dilemme qui se pose à propos de "La ligne ci-dessus permet d'imprimer la valeur 4, même lorsque
float num =4.9
." n'est pas explicable comme indiqué. Code supplémentaire/information est nécessaire. Je soupçonne OP peut-être utiliséint num = 4.9;
.Testé peu le faire plus tard quand j'ai le temps.
Je pense que ce que vous cherchez est:
int n = (d - floor(d) > 0.5) ? ceil(d) : floor(d);
la googlé code fonctionne correctement. L'idée derrière cela est que vous arrondissez vers le bas lorsque la décimale est inférieure à 5 et arrondir le contraire.
(int)
jette le float en int type qui tombe de la virgule. Si vous ajoutez .5 positif num, vous obtenez la baisse de la prochaine int. Si vous soustrayez .5 partir d'un négatif, il fait la même chose.Vous pouvez être en mesure d'utiliser
fesetround()
dansfenv.h
(introduit en C99). Les arguments possibles sont les macrosFE_DOWNWARD
,FE_TONEAREST
,FE_TOWARDZERO
, etFE_UPWARD
mais notez que tous ne sont pas nécessairement définies uniquement ceux pris en charge par la plate-forme/mise en œuvre sont. Ensuite, vous pouvez utiliser les différentsround
,rint
etnearbyint
fonctions dansmath.h
(également C99). De cette façon, vous pouvez définir l'arrondissement de comportement une fois et d'appeler la même fonction, indépendamment de savoir si ou non la valeur est positive ou négative.(Avec, par exemple,
lround
d'habitude vous n'avez même pas besoin de définir la direction de l'arrondissement pour l'utilisation normale de l'habitude d'obtenir ce que vous voulez.)Il sera plus rapide qu'une version avec plafond et plancher.
int(x + 0.5)
est invalide C. Algorithme échoue pourx just less than 0.5,
x` est pas près deint
gamme.Ronde de la valeur x à la précision p, avec 0 < p < infini. (f.ex. 0.25, 0.5, 1, 2,...)
int(...)
échoue devraitx*(...)
dépasser la gamme deint
.float
esttuncf(x)
.double trunc(double x)
est pourdouble
. Utilisationfloat truncf(float x);
pourfloat()
. Il peut être mathématiquement gaspillage d'utiliser le retour d'unfloat()
à l'aide defloat x; return double trunc(x)
.juste ajouter 0,5 pour le nombre et le transtypage il..
et de l'imprimer par type de moulage en entier..
sinon, vous pouvez aller avec round() à l'intérieur qui vient de passer l'argument que le nombre respectif.
Essayez de déplacer les crochets sur votre solution ci-dessus, afin qu'il se lise:
À l'aide de num comme 4.9 elle arrondit à 5 sur ma machine.
(int)
cast est redondant, carnum < 0
déjà a typeint
.