J'ai besoin d'une simple fonction d'arrondi à virgule flottante, donc:
double round(double);
round(0.1) = 0
round(-0.1) = 0
round(-0.9) = -1
Je peux trouver ceil()
et floor()
dans le math.h - mais pas round()
.
Est-il présent dans la bibliothèque C ++ standard sous un autre nom, ou est-il manquant ??
c++
floating-point
rounding
Roddy
la source
la source
std::cout << std::fixed << std::setprecision(0) << -0.9
, par exemple.round
est disponible depuis C ++ 11 dans<cmath>
. Malheureusement, si vous êtes dans Microsoft Visual Studio, il manque toujours: connect.microsoft.com/VisualStudio/feedback/details/775474/…round
comporte de nombreuses mises en garde. Avant C ++ 11, la norme s'appuyait sur C90 qui ne comprenait pasround
. C ++ 11 s'appuie sur C99 qui around
mais aussi comme je l'ai noté incluttrunc
qui a des propriétés différentes et peut être plus approprié en fonction de l'application. La plupart des réponses semblent également ignorer qu'un utilisateur peut souhaiter retourner un type intégral qui a encore plus de problèmes.Réponses:
Il n'y a pas de round () dans la bibliothèque standard C ++ 98. Vous pouvez cependant en écrire un vous-même. Ce qui suit est une mise en œuvre de demi-tour :
La raison probable qu'il n'y a pas de fonction ronde dans la bibliothèque standard C ++ 98 est qu'elle peut en fait être implémentée de différentes manières. Ce qui précède est un moyen courant, mais il y en a d'autres tels que l' arrondi au pair , qui est moins biaisé et généralement meilleur si vous allez faire beaucoup d'arrondis; c'est un peu plus complexe à implémenter.
la source
Boost propose un ensemble simple de fonctions d'arrondi.
Pour plus d'informations, consultez la documentation Boost .
Edition : Depuis C ++ 11, il y a
std::round
,std::lround
etstd::llround
.la source
floor(value + 0.5)
approche naïve !floor(value + 0.5)
.floor(value + 0.5)
n'est pas du tout naïf, mais plutôt dépend du contexte et de la nature des valeurs que vous souhaitez arrondir!La norme C ++ 03 s'appuie sur la norme C90 pour ce que la norme appelle la bibliothèque C standard qui est couverte dans le projet de norme C ++ 03 (le projet de norme le plus proche du C ++ 03 est N1804 ).
1.2
Références normatives :Si nous allons dans la documentation C pour round, lround, llround sur cppreference, nous pouvons voir que round et les fonctions associées font partie de C99 et ne seront donc pas disponibles en C ++ 03 ou avant.
En C ++ 11, cela change car C ++ 11 s'appuie sur le projet de norme C99 pour la bibliothèque de normes C et fournit donc std :: round et pour les types de retour intégrés std :: lround, std :: llround :
Une autre option également de C99 serait std :: trunc qui:
Si vous devez prendre en charge des applications non C ++ 11, votre meilleur pari serait d'utiliser le boost round, iround, lround, llround ou boost trunc .
Rouler sa propre version du tour est difficile
Faire rouler le vôtre ne vaut probablement pas la peine car plus difficile qu'il n'y paraît: arrondir le flottant à l'entier le plus proche, partie 1 , arrondir le flotteur à l'entier le plus proche, partie 2 et arrondir le flotteur à l'entier le plus proche, partie 3 explique:
Par exemple, un roll commun que votre implémentation utilise
std::floor
et ajoute0.5
ne fonctionne pas pour toutes les entrées:Une entrée pour laquelle cela échouera est
0.49999999999999994
( voir en direct ).Une autre implémentation courante consiste à convertir un type à virgule flottante en un type intégral, qui peut invoquer un comportement indéfini dans le cas où la partie intégrale ne peut pas être représentée dans le type de destination. Nous pouvons le voir dans le projet de section standard C ++
4.9
Conversions intégrale flottante qui dit (c'est moi qui souligne ):Par exemple:
Étant donné
std::numeric_limits<unsigned int>::max()
est4294967295
alors l'appel suivant:provoquera un débordement, ( voir en direct ).
Nous pouvons voir à quel point cela est vraiment difficile en regardant cette réponse à la manière concise d'implémenter round () en C? qui fait référence à newlibs version du flotteur simple précision. C'est une fonction très longue pour quelque chose qui semble simple. Il semble peu probable que quiconque sans connaissance intime des implémentations en virgule flottante puisse correctement implémenter cette fonction:
D'un autre côté, si aucune des autres solutions n'est utilisable, newlib pourrait potentiellement être une option car c'est une implémentation bien testée.
la source
round(-0.0)
. La spécification C ne semble pas spécifier. Je m'attendrais-0.0
en conséquence.std::rint()
c'est souvent préférablestd::round()
lorsque C ++ 11 est disponible pour des raisons numériques et de performances. Il utilise le mode d'arrondi actuel, contrairementround()
au mode spécial de. Il peut être beaucoup plus efficace sur x86, oùrint
peut s'aligner sur une seule instruction. (gcc et clang le font même sans-ffast-math
godbolt.org/g/5UsL2e , alors que seul clang insère le presque équivalentnearbyint()
) ARM a un support à instruction unique pourround()
, mais sur x86 il ne peut être en ligne qu'avec plusieurs instructions, et seulement avec-ffast-math
Il convient de noter que si vous voulez un résultat entier de l'arrondi, vous n'avez pas besoin de le faire passer par le plafond ou le sol. C'est à dire,
la source
Il est disponible depuis C ++ 11 dans cmath (selon http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf )
Production:
la source
lround
etllround
pour des résultats intégrauxlrint
pour utiliser le mode d'arrondi actuel au lieu duround
bris d'égalité génial loin de zéro.Il est généralement implémenté en tant que
floor(value + 0.5)
.Edit: et ce n'est probablement pas appelé arrondi car il y a au moins trois algorithmes d'arrondi que je connais: arrondi à zéro, arrondi à l'entier le plus proche et arrondi du banquier. Vous demandez l'arrondi à l'entier le plus proche.
la source
Nous examinons 2 problèmes:
Les conversions d'arrondi signifient l'arrondissement ± flottant / double au plancher / plafond le plus proche flottant / double. Peut-être que votre problème se termine ici. Mais si vous êtes censé retourner Int / Long, vous devez effectuer une conversion de type, et donc le problème de «débordement» peut frapper votre solution. SO, vérifiez une erreur dans votre fonction
à partir de: http://www.cs.tut.fi/~jkorpela/round.html
la source
LONG_MIN-0.5
etLONG_MAX+0.5
introduire des complications car les mathématiques peuvent ne pas être exactes.LONG_MAX
peut dépasser ladouble
précision pour une conversion exacte. De plus, vous souhaiterez probablementassert(x < LONG_MAX+0.5);
(<vs <=) car ilsLONG_MAX+0.5
peuvent être exactement représentables et(x)+0.5
peuvent avoir un résultat exactLONG_MAX+1
dont la conversion échouelong
. D'autres problèmes de coin aussi.round(double)
, il existe déjà une fonction de bibliothèque mathématique standard de ce nom (en C ++ 11), donc c'est déroutant. À utiliserstd::lrint(x)
s'il est disponible.Un certain type d'arrondi est également implémenté dans Boost:
Notez que cela ne fonctionne que si vous effectuez une conversion en nombre entier.
la source
boost:numeric::RoundEven< double >::nearbyint
directement si vous ne voulez pas de nombre entier. @DanielWolf note que la fonction simple est implémentée en utilisant +0.5 qui a des problèmes comme indiqué par aka.niceVous pouvez arrondir à une précision à n chiffres avec:
la source
int
. (En pratique sur x86, les valeurs FP hors plage feront que leCVTTSD2SI
produit sera0x80000000
le motif de bits entier, c'estINT_MIN
-à- dire qui sera ensuite reconverti endouble
.De nos jours, l'utilisation d'un compilateur C ++ 11 qui inclut une bibliothèque mathématique C99 / C ++ 11 ne devrait pas poser de problème. Mais alors la question devient: quelle fonction d'arrondi choisissez-vous?
C99 / C ++ 11
round()
n'est souvent pas la fonction d'arrondi souhaitée . Il utilise un mode d'arrondi génial qui arrondit à partir de 0 comme bris d'égalité sur les cas à mi-chemin (+-xxx.5000
). Si vous voulez spécifiquement ce mode d'arrondi, ou si vous ciblez une implémentation C ++ oùround()
est plus rapide querint()
, alors utilisez-le (ou émulez son comportement avec l'une des autres réponses à cette question qui l'a pris au pied de la lettre et reproduit soigneusement ce spécifique comportement d'arrondi.)round()
L'arrondi est différent de l'arrondi par défaut IEEE754 au mode le plus proche, même en cas d'égalité . Le plus proche pair évite un biais statistique dans la magnitude moyenne des nombres, mais fait un biais vers les nombres pairs.Il existe deux fonctions d'arrondi de bibliothèque mathématique qui utilisent le mode d'arrondi par défaut actuel:
std::nearbyint()
etstd::rint()
, toutes deux ajoutées en C99 / C ++ 11, elles sont donc disponibles à tout momentstd::round()
. La seule différence est quenearbyint
ne soulève jamais FE_INEXACT.Préférez
rint()
pour des raisons de performances : gcc et clang l'inline plus facilement, mais gcc ne s'aligne jamaisnearbyint()
(même avec-ffast-math
)gcc / clang pour x86-64 et AArch64
J'ai mis quelques fonctions de test sur l'explorateur de compilateur de Matt Godbolt , où vous pouvez voir la sortie source + asm (pour plusieurs compilateurs). Pour en savoir plus sur la lecture de la sortie du compilateur, consultez ce Q&R et la conférence CppCon2017 de Matt: «Qu'est-ce que mon compilateur a fait pour moi récemment? Déboulonnage du couvercle du compilateur » ,
Dans le code FP, c'est généralement une grande victoire pour intégrer de petites fonctions. Surtout sur non-Windows, où la convention d'appel standard n'a pas de registres préservés, donc le compilateur ne peut pas conserver de valeurs FP dans les registres XMM à travers a
call
. Ainsi, même si vous ne connaissez pas vraiment asm, vous pouvez toujours voir facilement s'il s'agit simplement d'un appel à la fonction de bibliothèque ou s'il est aligné sur une ou deux instructions mathématiques. Tout ce qui s'aligne sur une ou deux instructions est meilleur qu'un appel de fonction (pour cette tâche particulière sur x86 ou ARM).Sur x86, tout ce qui s'aligne sur SSE4.1
roundsd
peut se vectoriser automatiquement avec SSE4.1roundpd
(ou AVXvroundpd
). (Les conversions FP-> integer sont également disponibles sous forme SIMD compactée, sauf pour FP-> 64-bit integer qui nécessite AVX512.)std::nearbyint()
:-msse4.1
.-msse4.1 -ffast-math
et uniquement sur gcc 5.4 et versions antérieures . Plus tard, gcc ne l'inline jamais (peut-être qu'ils ne se sont pas rendu compte que l'un des bits immédiats peut supprimer l'exception inexacte? C'est ce que clang utilise, mais l'ancien gcc utilise le même immédiat querint
lorsqu'il le fait en ligne)std::rint
:-msse4.1
-msse4.1
. (Sans SSE4.1, s'aligne sur plusieurs instructions)-ffast-math -msse4.1
.std::round
:-ffast-math -msse4.1
, nécessitant deux constantes vectorielles.std::floor
/std::ceil
/std::trunc
-msse4.1
-msse4.1
-ffast-math -msse4.1
Arrondi à
int
/long
/long long
:Vous avez deux options ici: utiliser
lrint
(commerint
mais renvoielong
, oulong long
pourllrint
), ou utiliser une fonction d'arrondi FP-> FP, puis convertir en type entier de la manière normale (avec troncature). Certains compilateurs optimisent dans un sens mieux que dans l'autre.Notez que
int i = lrint(x)
convertitfloat
oudouble
-> d'long
abord, puis tronque l'entier enint
. Cela fait une différence pour les entiers hors plage: Comportement non défini en C ++, mais bien défini pour les instructions x86 FP -> int (que le compilateur émettra à moins qu'il ne voit l'UB au moment de la compilation tout en faisant une propagation constante, alors c'est autorisé à faire du code qui se casse s'il est déjà exécuté).Sur x86, une conversion FP-> entier qui déborde de l'entier produit
INT_MIN
ouLLONG_MIN
(un modèle de bits de0x8000000
ou l'équivalent 64 bits, avec juste le bit de signe défini). Intel appelle cela la valeur "indéfinie entière". (Voir l'cvttsd2si
entrée manuelle , l'instruction SSE2 qui convertit (avec troncature) scalaire double en entier signé. Elle est disponible avec une destination entière 32 bits ou 64 bits (en mode 64 bits uniquement). Il y a aussi uncvtsd2si
(convertir avec l'arrondi actuel mode), ce que nous aimerions que le compilateur émette, mais malheureusement gcc et clang ne le feront pas sans-ffast-math
.Sachez également que FP vers / depuis
unsigned
int / long est moins efficace sur x86 (sans AVX512). La conversion en 32 bits non signé sur une machine 64 bits est assez bon marché; il suffit de convertir en 64 bits signé et de tronquer. Mais sinon, c'est beaucoup plus lent.x86 clang avec / sans
-ffast-math -msse4.1
: en(int/long)rint
ligne versroundsd
/cvttsd2si
. (optimisation manquée pourcvtsd2si
).lrint
ne s'aligne pas du tout.x86 gcc6.x et versions antérieures sans
-ffast-math
: aucune façon ne s'aligne-ffast-math
:(int/long)rint
arrondit et convertit séparément (avec 2 instructions totales de SSE4.1 est activé, sinon avec un tas de code en ligne pourrint
sansroundsd
).lrint
ne s'aligne pas.x86 gcc avec
-ffast-math
: toutes les manières en ligne àcvtsd2si
(optimal) , pas besoin de SSE4.1.AArch64 gcc6.3 sans
-ffast-math
:(int/long)rint
s'aligne sur 2 instructions.lrint
ne s'aligne pas-ffast-math
:(int/long)rint
compile un appel àlrint
.lrint
ne s'aligne pas. Il peut s'agir d'une optimisation manquée, à moins que les deux instructions dont nous sommes privés-ffast-math
soient très lentes.la source
rint()
où c'est un choix faisable, ce qui est généralement le cas. Je suppose que le nomround()
implique pour certains programmeurs que c'est ce qu'ils veulent, alors que celarint()
semble mystérieux. Notez queround()
n'utilise pas un mode d'arrondi "génial": l'arrondi au plus proche est un mode d'arrondi officiel IEEE-754 (2008). C'est curieux quinearbyint()
ne soit pas aligné, étant donné qu'il est en grande partie identique àrint()
, et devrait être identique sous certaines-ffast-math
conditions. Cela me semble bête.Méfiez-vous
floor(x+0.5)
. Voici ce qui peut arriver pour les nombres impairs dans la plage [2 ^ 52,2 ^ 53]:Il s'agit de http://bugs.squeak.org/view.php?id=7134 . Utilisez une solution comme celle de @konik.
Ma propre version robuste serait quelque chose comme:
Une autre raison pour éviter le plancher (x + 0,5) est donnée ici .
la source
Si vous souhaitez finalement convertir la
double
sortie de votreround()
fonction en unint
, les solutions acceptées de cette question ressembleront à:Cela se produit à environ 8,88 ns sur ma machine lorsqu'il est transmis en valeurs uniformément aléatoires.
Pour autant que je sache, les fonctionnalités ci-dessous sont équivalentes, mais elles se cadencent à 2,48 ns sur ma machine, pour un avantage de performance significatif:
Parmi les raisons de la meilleure performance est la ramification ignorée.
la source
int
. (En pratique sur x86, les valeurs de FP hors plage feront que leCVTTSD2SI
produit sera0x80000000
le modèle de bits entier, c'estINT_MIN
-à- dire qui sera ensuite reconverti endouble
.Il n'est pas nécessaire d'implémenter quoi que ce soit, donc je ne sais pas pourquoi tant de réponses impliquent des définitions, des fonctions ou des méthodes.
En C99
Nous avons les en-têtes et et <tgmath.h> pour les macros de type générique.
Si vous ne pouvez pas compiler cela, vous avez probablement omis la bibliothèque mathématique. Une commande similaire à celle-ci fonctionne sur tous les compilateurs C que j'ai (plusieurs).
En C ++ 11
Nous avons les surcharges suivantes et supplémentaires dans #include <cmath> qui reposent sur la virgule flottante double précision IEEE.
Il y a aussi des équivalents dans l'espace de noms std .
Si vous ne pouvez pas compiler cela, vous utilisez peut-être la compilation C au lieu de C ++. La commande de base suivante ne produit ni erreurs ni avertissements avec g ++ 6.3.1, x86_64-w64-mingw32-g ++ 6.3.0, clang-x86_64 ++ 3.8.0 et Visual C ++ 2015 Community.
Avec division ordinale
Lorsque vous divisez deux nombres ordinaux, où T est court, int, long ou un autre ordinal, l'expression d'arrondi est la suivante.
Précision
Il ne fait aucun doute que des imprécisions d'aspect étrange apparaissent dans les opérations en virgule flottante, mais ce n'est que lorsque les chiffres apparaissent, et n'a pas grand-chose à voir avec l'arrondi.
La source n'est pas seulement le nombre de chiffres significatifs dans la mantisse de la représentation IEEE d'un nombre à virgule flottante, elle est liée à notre pensée décimale en tant qu'êtres humains.
Dix est le produit de cinq et deux, et 5 et 2 sont relativement premiers. Par conséquent, les normes à virgule flottante IEEE ne peuvent pas être représentées parfaitement sous forme de nombres décimaux pour toutes les représentations numériques binaires.
Ce n'est pas un problème avec les algorithmes d'arrondi. C'est la réalité mathématique qui doit être prise en compte lors de la sélection des types et de la conception des calculs, de la saisie des données et de l'affichage des nombres. Si une application affiche les chiffres qui montrent ces problèmes de conversion décimal-binaire, alors l'application exprime visuellement une précision qui n'existe pas dans la réalité numérique et doit être modifiée.
la source
Fonction
double round(double)
avec l'utilisation de lamodf
fonction:Pour être propre à la compilation, il faut des "math.h" et des "limites". La fonction fonctionne selon un schéma d'arrondi suivant:
la source
rint()
ounearbyint()
, mais si vous ne pouvez vraiment pas utiliser un compilateur qui fournit une fonction d'arrondi appropriée et que vous avez besoin de précision plus que de performances ...Si vous devez pouvoir compiler du code dans des environnements qui prennent en charge la norme C ++ 11, mais devez également pouvoir compiler ce même code dans des environnements qui ne le prennent pas en charge, vous pouvez utiliser une macro de fonction pour choisir entre std :: round () et une fonction personnalisée pour chaque système. Passez simplement
-DCPP11
ou/DCPP11
au compilateur compatible C ++ 11 (ou utilisez ses macros de version intégrées), et créez un en-tête comme celui-ci:Pour un exemple rapide, voir http://ideone.com/zal709 .
Cela se rapproche de std :: round () dans des environnements qui ne sont pas conformes à C ++ 11, y compris la préservation du bit de signe pour -0.0. Cependant, il peut entraîner une légère baisse des performances et il est probable que des problèmes d'arrondi de certaines valeurs en virgule flottante "problème" connus, tels que 0,4999999999999999994 ou des valeurs similaires, aient des problèmes.
Alternativement, si vous avez accès à un compilateur compatible C ++ 11, vous pouvez simplement saisir std :: round () de son en-
<cmath>
tête et l'utiliser pour créer votre propre en-tête qui définit la fonction si elle n'est pas déjà définie. Notez que cela peut ne pas être une solution optimale, cependant, surtout si vous devez compiler pour plusieurs plates-formes.la source
Sur la base de la réponse de Kalaxy, la solution suivante est un modèle qui arrondit tout nombre à virgule flottante au type entier le plus proche en fonction de l'arrondi naturel. Il génère également une erreur en mode débogage si la valeur est hors de portée du type entier, servant ainsi à peu près comme une fonction de bibliothèque viable.
la source
0.5
ne fonctionne pas dans tous les cas. Bien qu'au moins vous traitez le problème de débordement, vous évitez ainsi un comportement indéfini.Comme indiqué dans les commentaires et autres réponses, la bibliothèque standard ISO C ++ n'a pas ajouté
round()
jusqu'à ISO C ++ 11, lorsque cette fonction a été interceptée par référence à la bibliothèque mathématique standard ISO C99.Pour les opérandes positifs dans [½, ub ]
round(x) == floor (x + 0.5)
, où ub est 2 23 pourfloat
lorsqu'il est mappé à IEEE-754 (2008)binary32
et 2 52 pourdouble
quand il est mappé à IEEE-754 (2008)binary64
. Les nombres 23 et 52 correspondent au nombre de bits de mantisse stockés dans ces deux formats à virgule flottante. Pour les opérandes positifs dans [+0, ½)round(x) == 0
et pour les opérandes positifs dans ( ub , + ∞]round(x) == x
. Comme la fonction est symétrique par rapport à l'axe des x, les arguments négatifsx
peuvent être traités selonround(-x) == -round(x)
.Cela conduit au code compact ci-dessous. Il se compile en un nombre raisonnable d'instructions machine sur différentes plates-formes. J'ai observé le code le plus compact sur les GPU, où
my_roundf()
nécessite une dizaine d'instructions. Selon l'architecture du processeur et la chaîne d'outils, cette approche basée sur des virgules flottantes pourrait être plus rapide ou plus lente que l'implémentation basée sur des nombres entiers de newlib référencée dans une réponse différente .J'ai testé
my_roundf()
exhaustivement l'roundf()
implémentation de newlib en utilisant le compilateur Intel version 13, avec les deux/fp:strict
et/fp:fast
. J'ai également vérifié que la version de newlib correspond à celleroundf()
de lamathimf
bibliothèque du compilateur Intel. Des tests exhaustifs ne sont pas possibles pour la double précisionround()
, mais le code est structurellement identique à l'implémentation en simple précision.la source
int
une largeur supérieure à 16 bits. Bien entendu, il suppose toujours qu'ilfloat
s'agit d'un binaire32 IEEE754 à 4 octets. Un C ++ 11static_assert
ou peut-être une macro#ifdef
/#error
pourrait vérifier cela. (Mais bien sûr, si C ++ 11 est disponible, vous devez utiliserstd::round
, ou pour le mode d'arrondi actuel utiliserstd::rint
qui s'harmonise bien avec gcc et clang).gcc -ffast-math -msse4.1
s'alignestd::round()
sur unadd( AND(x, L1), OR(x,L2)
, puis sur aroundsd
. c'est-à-dire qu'il metround
en œuvre assez efficacement en termes derint
. Mais il n'y a aucune raison de le faire manuellement dans la source C ++, car si vous avezstd::rint()
ou questd::nearbyint()
vous avez égalementstd::round()
. Voir ma réponse pour un lien Godbolt et un aperçu de ce qui est en ligne ou non avec différentes versions de gcc / clang.round()
efficacement en termes derint()
(lorsque ce dernier fonctionne en mode arrondi au plus proche ou même): j'ai implémenté cela pour la bibliothèque mathématique standard CUDA. Cependant, cette question semblait demander comment implémenterround()
avec C ++ avant C ++ 11, doncrint()
ne serait pas disponible non plus, seulementfloor()
etceil()
.round()
est facilement synthétisé à partirrint()
du mode arrondi à zéro , aliastrunc()
. N'aurait pas dû répondre avant le premier café.round()
; la plupart des programmeurs ne sont tout simplement pas conscients de la distinction entreround()
vsrint()
avec arrondi au plus proche pair, où ce dernier est généralement fourni directement par le matériel et donc plus efficace; J'ai énoncé cela dans le Guide de programmation CUDA pour informer les programmeurs: «La méthode recommandée pour arrondir un opérande à virgule flottante simple précision en un entier, avec pour résultat un nombre à virgule flottante simple précisionrintf()
, n'est pasroundf()
».J'utilise l'implémentation suivante de round in asm pour l'architecture x86 et C ++ spécifique à MS VS:
UPD: pour retourner une valeur double
Production:
la source
rint()
ounearbyint()
vers uneroundsd
instruction SSE4.1 ou unefrndint
instruction x87 , ce qui sera beaucoup plus rapide que les deux allers-retours de stockage / rechargement nécessaires pour utiliser cet asm en ligne sur les données d'un registre. MSVC inline asm aspire beaucoup pour encapsuler des instructions uniques commefrndint
parce qu'il n'y a aucun moyen d'obtenir l'entrée dans un registre. L'utiliser à la fin d'une fonction avec le résultat dansst(0)
pourrait être fiable comme moyen de renvoyer la sortie; apparemment, cela est sans danger pour leseax
entiers, même lorsqu'il insère la fonction contenant l'asm.double
, et devrait donc pouvoir s'émettrefrndint
pourrint()
. Si votre compilateur utilise SSE2, faire rebondir un àdouble
partir d'un registre XMM vers x87 et inversement peut ne pas en valoir la peine.La meilleure façon d'arrondir une valeur flottante par "n" décimales, est la suivante avec en temps O (1): -
Nous devons arrondir la valeur de 3 places, c'est-à-dire n = 3.
la source
C'est peut-être un moyen de conversion sale inefficace, mais bon sang, ça marche lol. Et c'est bien, car cela s'applique au flotteur réel. N'affecte pas seulement visuellement la sortie.
la source
J'ai fait ça:
la source