Comment arrondir correctement les nombres à virgule flottante IEEE 754 sur la ligne de commande?
Je veux spécifier la précision du numéro de sortie - le nombre de chiffres fractionnaires.
L'arrondi 6.66
à la précision 1
devrait donner 6.7
, par exemple. Plus dans le tableau ci-dessous:
Value Precision Rounded
6.66 0 7
6.66 1 6.7
6.66 2 6.66
6.66 3 6.660
6.666 3 6.666
6.6666 3 6.667
Il devrait être utilisable dans un shell interactif, mais idéalement suffisamment robuste pour l'utiliser dans des scripts shell de production.
bash
command-line
arithmetic
floating-point
Volker Siegel
la source
la source
awk
.Réponses:
Arrondir les nombres à virgule flottante
Que signifie «arrondir un nombre à virgule flottante»?
C'est facile, évidemment ... Où est mon livre de mathématiques de l'école ...
Non, nous savons déjà que rien en rapport avec les nombres à virgule flottante n'est facile:
Pour commencer, il existe plusieurs modes d'arrondi:
Comment gérer les valises d'angle? Comment savoir quels sont les cas d'angle?
OK, il semble que nous devrions mieux utiliser une implémentation de la norme IEEE 754 et laisser notre système s'en occuper.
Pour arrondir un nombre à virgule flottante dans le shell, basé sur l'arithmétique à virgule flottante standard, nous avons besoin de trois étapes:
Il s'avère que la commande shell
printf
peut faire tout cela. Il peut être utilisé pour imprimer des nombres selon une spécification de format comme décrit dansman 3 printf
. Les nombres sont arrondis implicitement de la manière standard si cela est requis pour le format de sortie:La commande
Arrondir
x
à lap
précision des chiffres avec entrée comme arguments de ligne de commande:Ou dans un pipeline shell, avec entrée de
x
sur entrée standard, etp
comme argument:Exemples:
Mauvais pièges
Méfiez-vous des paramètres régionaux! Il spécifie le séparateur entre la partie intégrale et la partie fractionnaire - le
.
, comme vous pouvez vous y attendre.Mais voyez-vous ce qui se passe dans une langue allemande, par exemple:
Oui, c'est vrai
6,667
- six virgules six six sept. Cela gâcherait votre script à coup sûr.(Mais uniquement pour les deux clients en Allemagne. À l'exception des machines du développeur en cours de débogage pour ces clients.)
Plus robuste
Pour le rendre plus robuste, utilisez:
ou
Cela utilise également à la
/usr/bin/printf
place du shell intégré àbash
ouzsh
pour contourner les incohérences mineures dans l'implémentation desprintf
variantes, et empêche un effet très sale lorsque, dans une langue allemande,LC_ALL
est défini, mais pas exporté. Ensuite, le builtin utilise,
et/usr/bin/printf
utilise.
...Voir aussi
%g
pour arrondir à un nombre spécifié de chiffres significatifs.la source
La suite a fonctionné pour moi.
la source