7
votes

C ++ arrondir des nombres loin de zéro

Bonjour, je veux rond de doubles numéros comme celui-ci (loin de zéro) en C ++: xxx

Quel est le moyen efficace de le faire?


1 commentaires

Du titre (original) "C ++ double arrondi", je pensais que vous vouliez dire deux fois par exemple, juste pour être sûr :-)


4 Réponses :


0
votes

Essayez

 double rounded = _copysign(ceil(abs(x)), x);


6 commentaires

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 à 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 = 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.



25
votes
x = (x < 0) ? floor(x) : ceil(x);

2 commentaires

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



3
votes

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;
}


5 commentaires

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 floattype ceil0 (const floattype & valeur) {flattype résultat = std :: CEIL (STD :: fabs (valeur)); retour (valeur <0,0)? -Result: résultat; } article intéressant, +1


@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/... (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)



2
votes

Le x <0? Plancher (x): CEIL (X); Approche de Ruben Bartelink est bon. Pourtant, considérons ce qui se passe avec des cas spéciaux de x = -0,0 , x = nan .

plutôt que myround (-0.0) potentiellement retour +0.0 1 et avoir myround (NAN) retour avec une charge utile modifiée du NAN , considérez ci-dessous. .

myround_alt (-0.0) retourne -0.0 .

myround_alt (NAN) < EM> plus susceptibles 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) -> -0.0 je cherche. xxx


1 IEC 60559 Arithmétique à point flottant Spécifie CEIL (± 0) renvoie ± 0 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.


0 commentaires