Bonjour, je veux rond de doubles numéros comme celui-ci (loin de zéro) en C ++: Quel est le moyen efficace de le faire? p> p>
4 Réponses :
Essayez
double rounded = _copysign(ceil(abs(x)), x);
Mais le plafond retourne plus grand valeur entière si ma valeur est -3,4 et j'ajoute 0,5, il sera de -2,9 et ceil retournera -2, je veux quelque chose à faire -4
CEIL (x + 0,5) pour x = 5,7 donnerait 7 au lieu de 6, n'est-ce pas?
Il ne fonctionne toujours pas pour les négatifs comme spécifiques, voir les échantillons à l'endroit où j'ai lié.
Maintenant, ce n'est plus aussi efficace, même s'il utilise une astuce intéressante - où est _copysign de?
C'est une bonne technique: un compilateur / point d'exécution intelligent doit autoriser le bit abs code> à bit-et le pit-signal avec 0, faites le plafond (priez pour que cela soit fait rapidement), puis relance le résultat par Bit-oring son bit de signe avec l'original. Pas de conditionnement i> = Aucune branche MIS-PRÉDICTIONS = Aucun flus de pipeline = très rapide.
Pourquoi cela a-t-il voté? La réponse donnée ici était fausse avant, mais après la correction, c'est maintenant une bonne réponse. Comme @ahmed Fasih a souligné, cette solution ne nécessite que quelque peu et et une opération, elle devrait donc être rapide avec une faible latence.
x = (x < 0) ? floor(x) : ceil(x);
Bon appel, @Ruben, a ajouté une variante non-fonction et vous a donné un vote. J'espère que cela ne vous dérange pas (le changement, c'est évidemment que cela ne vous dérange pas du vote).
En attente de 3k moi-même - ajouté dans un spécificateur en ligne - j'aurais tendance à essayer de trouver un bon nom et de le coller dans un util lib, probablement comme un gabarit pour tous les floats - cela ne coûterait aucune efficacité et vous permet d'isoler rapidement ou changer tous les usages de celui-ci
Il y a un bel article sur un problème similaire sur Cplusplus.com . La solution facile à votre problème devrait être quelque chose comme ceci:
//-------------------------------------------------------------------------- // symmetric round up // Bias: away from zero template <typename FloatType> FloatType ceil0( const FloatType& value ) { FloatType result = std::ceil( std::fabs( value ) ); return (value < 0.0) ? -result : result; }
Pourquoi n'est-ce pas appelé plancher coutumier - ce n'est pas non plus: p
Je vois dans l'article cité son implication en tant que modèle
@Ruben Bartelink: «Tour» devrait être mieux :) ... BTW ... vous avez des compétences en dactylographie Ninja ;-)
Taper ou couper et coller: P Ma dactylographie est en fait assez embarrassant - voir blog.jpboodhoo.com/.../ a> (non, ne l'a pas encore fait). Je pense que même "tour" est un peu générique et a une signification généralement comprise dans le point de STDLIB est son algorithme très spécifique qu'il souhaite, et l'utilisation de l'étage, du CEIL ou du rond ne transmettent pas exactement cela.
Puisque vous ramifiez quand même, la valeur absolue est quelque peu redondante: retour (valeur <0,0)? -Std :: CEIL (-Value): STD :: CEIL (Valeur) Code>
Le plutôt que 1 sup> IEC 60559 Arithmétique à point flottant Spécifie x <0? Plancher (x): CEIL (X); Code> Approche de Ruben Bartelink est bon. Pourtant, considérons ce qui se passe avec des cas spéciaux de
x = -0,0 code>,
x = nan code>.
myround (-0.0) code> potentiellement retour
+0.0 code> 1 sup> et avoir
myround (NAN) code> retour avec une charge utile modifiée du
NAN code>, considérez ci-dessous. . p>
myround_alt (-0.0) code> retourne
-0.0 code>. p>
myround_alt (NAN) code> < EM> plus susceptibles em> retourne un Nan de charge utile inchangé. Stuff non-Number est délicat et pas bien défini. Iac, il est le
myround_alt (-0,0) code> ->
-0.0 code> je cherche. P>
CEIL (± 0) code> renvoie
± 0 code> Cette approche pas nécessaire avec des implémentations qui suivent strictement cette spécification. Pourtant, beaucoup de la mise en œuvre du point flottant ne suit pas que (c ne le nécessite pas) ou échoue dans de tels cas de venue comme celui-ci. P> P>
Du titre (original) "C ++ double arrondi", je pensais que vous vouliez dire deux fois par exemple, juste pour être sûr :-)