Comment arrondir un nombre décimal (virgule flottante) à l'entier le plus proche?
par exemple
1.2 = 1
1.7 = 2
la source
Comment arrondir un nombre décimal (virgule flottante) à l'entier le plus proche?
par exemple
1.2 = 1
1.7 = 2
Sortie de perldoc -q round
Perl a-t-il une fonction round ()? Qu'en est-il de ceil () et floor ()? Fonctions de déclenchement?Rappelez-vous que cela
int()
tronque simplement vers0
. Pour arrondir à un certain nombre de chiffres,sprintf()
ouprintf()
est généralement l'itinéraire le plus simple.
printf("%.3f", 3.1415926535); # prints 3.142
Le
POSIX
module (partie de la distribution standard de Perl) met en œuvreceil()
,floor()
et un certain nombre d'autres fonctions mathématiques et trigonométriques.
use POSIX; $ceil = ceil(3.5); # 4 $floor = floor(3.5); # 3
Dans 5.000 à 5.003 perls, la trigonométrie a été effectuée dans le
Math::Complex
module. Avec 5.004, leMath::Trig
module (qui fait partie de la distribution standard de Perl) implémente les fonctions trigonométriques. En interne, il utilise leMath::Complex
module et certaines fonctions peuvent sortir de l'axe réel dans le plan complexe, par exemple le sinus inverse de 2.L'arrondi dans les applications financières peut avoir de graves implications et la méthode d'arrondi utilisée doit être spécifiée avec précision. Dans ces cas, il vaut probablement mieux ne pas faire confiance à l'arrondi système utilisé par Perl, mais plutôt implémenter la fonction d'arrondi dont vous avez besoin.
Pour voir pourquoi, remarquez que vous aurez toujours un problème sur l'alternance à mi-chemin:
for ($i = 0; $i < 1.01; $i += 0.05) { printf "%.1f ",$i} 0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.8 0.9 0.9 1.0 1.0
Ne blâmez pas Perl. C'est la même chose que dans C. IEEE dit que nous devons le faire. Les nombres Perl dont les valeurs absolues sont des entiers inférieurs
2**31
(sur les machines 32 bits) fonctionneront à peu près comme des entiers mathématiques. Les autres numéros ne sont pas garantis.
printf
si vous voulez le résultat dans une variable, utilisezsprintf
... j'espère que cela vous fera gagner du temps de débogage :-Pint()
sur les PDL?Sans être en désaccord avec les réponses complexes sur les notes à mi-chemin et ainsi de suite, pour le cas d'utilisation le plus courant (et peut-être trivial):
my $rounded = int($float + 0.5);
METTRE À JOUR
S'il est possible que vous
$float
soyez négatif, la variation suivante produira le résultat correct:my $rounded = int($float + $float/abs($float*2 || 1));
Avec ce calcul, -1,4 est arrondi à -1 et -1,6 à -2, et zéro n'explosera pas.
la source
Vous pouvez soit utiliser un module comme Math :: Round :
Ou vous pouvez le faire de manière grossière:
la source
Si vous décidez d'utiliser printf ou sprintf, notez qu'ils utilisent la méthode Round half to even .
la source
Voir perldoc / perlfaq :
la source
Vous n'avez besoin d'aucun module externe.
Votre argument me manque peut-être, mais je pensais que c'était une manière beaucoup plus propre de faire le même travail.
Cela permet de parcourir chaque nombre positif de l'élément, d'imprimer le nombre et l'entier arrondi dans le format que vous avez mentionné. Le code concatène un entier positif arrondi respectif uniquement en fonction des décimales. int ($ _) essentiellement rond vers le bas le nombre si ($ -INT ($ )) capture les décimales. Si les décimales sont (par définition) strictement inférieures à 0,5, arrondissez le nombre à la baisse. Sinon, arrondissez en ajoutant 1.
la source
Ce qui suit arrondira les nombres positifs ou négatifs à une position décimale donnée:
la source
Voici un exemple de cinq façons différentes de sommer les valeurs. Le premier est une manière naïve d'effectuer la sommation (et échoue). La seconde tente d'utiliser
sprintf()
, mais elle échoue aussi. Le troisième utilisesprintf()
avec succès tandis que les deux derniers (4e et 5e) utilisentfloor($value + 0.5)
.Notez que
floor($value + 0.5)
peut être remplacé parint($value + 0.5)
pour supprimer la dépendance surPOSIX
.la source
Les nombres négatifs peuvent ajouter des bizarreries dont les gens doivent être conscients.
printf
-Les approches de style nous donnent des nombres corrects, mais elles peuvent entraîner des affichages étranges. Nous avons découvert que cette méthode (à mon avis, bêtement) met un-
signe si oui ou non elle devrait ou non. Par exemple, -0,01 arrondi à une décimale renvoie un -0,0, plutôt que juste 0. Si vous allez faire l'printf
approche de style, et que vous savez que vous ne voulez pas de décimale, utilisez%d
et non%f
(lorsque vous avez besoin de décimales, c'est quand le l'affichage devient bancal).Bien que ce soit correct et pour les mathématiques, ce n'est pas un problème, pour l'affichage, cela semble bizarre en montrant quelque chose comme "-0.0".
Pour la méthode int, les nombres négatifs peuvent changer ce que vous voulez en conséquence (bien que certains arguments puissent être avancés, ils sont corrects).
La
int + 0.5
cause des problèmes réels avec des numéros séronégatifs, sauf si vous voulez que cela fonctionne de cette façon, mais j'imagine que la plupart des gens ne le font pas. -0,9 devrait probablement arrondir à -1, pas à 0. Si vous savez que vous voulez que le négatif soit un plafond plutôt qu'un plancher, vous pouvez le faire en une seule ligne, sinon, vous voudrez peut-être utiliser la méthode int avec un mineur modification (cela ne fonctionne évidemment que pour récupérer des nombres entiers:la source
Ma solution pour sprintf
la source
Si vous ne souhaitez obtenir qu'une valeur entière à partir d'un nombre entier à virgule flottante (c'est-à-dire 12347,9999 ou 54321,0001), cette approche (empruntée et modifiée par le haut) fera l'affaire:
la source
beaucoup de documentation de lecture sur la façon d'arrondir les nombres, de nombreux experts suggèrent d'écrire vos propres routines d'arrondi, car la version «en conserve» fournie avec votre langue peut ne pas être assez précise ou contenir des erreurs. J'imagine, cependant, qu'ils parlent de nombreuses décimales, pas seulement un, deux ou trois. dans cet esprit, voici ma solution (bien que pas EXACTEMENT aussi demandé que mes besoins sont d'afficher des dollars - le processus n'est pas très différent, cependant).
la source
if ($digit3 >= 5) { $digit3 = 0; $digit2++; if ($digit2 > 9) { $digit2 = 0; $digit1++; if ($digit1 > 9) { $digit1 = 0; $cost[0]++; } } }
donc c'est:if ($digit1 >= 5) { $digit1 = 0; $cost[0]++; }
alors justereturn commafied($cost[0]);
la source