328 votes

Comment utiliser la division en virgule flottante en bash ?

J'essaie de diviser deux largeurs d'image dans un script de Bash, mais bash me donne 0 comme résultat :

RESULT=$(($IMG_WIDTH/$IMG2_WIDTH))

J'ai étudié le guide Bash et je sais que je devrais utiliser bc Dans tous les exemples sur Internet, ils utilisent bc . Sur echo J'ai essayé de mettre la même chose dans mon SCALE mais ça n'a pas marché.

Voici l'exemple que j'ai trouvé dans les tutoriels :

echo "scale=2; ${userinput}" | bc 

Comment faire pour que Bash me donne un flotteur du genre 0.5 ?

10 votes

Un commentaire pour tous ceux qui essaient de faire de l'arithmétique à virgule flottante dans leur script, demandez-vous : ai-je vraiment besoin de l'arithmétique à virgule flottante ? parfois on peut vraiment s'en passer. Voir, par exemple, la dernière partie de BashFAQ/022 .

311voto

Ignacio Vazquez-Abrams Points 312628

Tu ne peux pas. uniquement fait les nombres entiers ; vous doit délégué à un outil tel que bc .

14 votes

Comment puis-je déléguer un outil comme bc in pour mettre la réponse dans la variable RESULT ?

2 votes

Vous voulez donc dire VAR=$(echo "scale=2 ; $(($IMG_WIDTH/$IMG2_WIDTH))" | bc) ?

72 votes

@Shevin VAR=$(echo "scale=2; $IMG_WIDTH/$IMG2_WIDTH" | bc) o VAR=$(bc <<<"scale=2;$IMG_WIDTH/$IMG2_WIDTH") sans $(( )) (double parenthèse) ; qui est développé par le bash avant d'exécuter la commande

269voto

Ayoubi Points 2390

Vous pouvez le faire :

bc <<< 'scale=2; 100/3'
33.33

UPDATE 20130926 : vous pouvez utiliser :

bc -l <<< '100/3' # saves a few hits
33.33333333333333333333

16 votes

@AndreasSpindler Il s'agit d'un vieux message, mais au cas où quelqu'un voudrait le savoir, cela peut être modifié en appliquant la commande d'échelle, par exemple. bc -l <<< 'scale=2; 100/3'

0 votes

Faites juste attention si vous espérez obtenir un entier pour une utilisation ultérieure dans bash en utilisant scale=0. Depuis la v1.06.95, bc, pour une raison quelconque, ignore la variable scale lorsque les nombres en entrée ont une partie décimale. Peut-être que cela se trouve dans la documentation, mais je ne l'ai pas trouvé. Essayez : echo $(bc -l <<< 'scale=0 ; 1*3.3333')

1 votes

@GregBell La page de manuel dit Unless specifically mentioned the scale of the result is the maximum scale of the expressions involved. Et il y a une note supplémentaire pour / opérateur : The scale of the result is the value of the variable scale.

45voto

adrianlzt Points 69

Améliorer un peu la réponse de Marvin :

RESULT=$(awk "BEGIN {printf \"%.2f\",${IMG_WIDTH}/${IMG2_WIDTH}}")

bc ne vient pas toujours en tant que paquet installé.

5 votes

L'awk script a besoin d'un fichier exit pour l'empêcher de lire à partir de son flux d'entrée. Je suggère également d'utiliser la fonction -v des drapeaux pour prévenir le syndrome du cure-dent penché. Donc : RESULT=$(awk -v dividend="${IMG_WIDTH}" -v divisor="${IMG2_WIDTH}" 'BEGIN {printf "%.2f", dividend/divisor; exit(0)}')

3 votes

Une façon plus awkish de faire cela serait de lire les arguments depuis le flux d'entrée : RESULT=$(awk '{printf("result= %.2f\n",$1/$2)}' <<<" $IMG_WIDTH $IMG2_WIDTH " .

1 votes

bc fait partie de POSIX, il est généralement préinstallé.

41voto

user1314742 Points 41

Vous pourriez utiliser bc par le -l option (la lettre L)

RESULT=$(echo "$IMG_WIDTH/$IMG2_WIDTH" | bc -l)

5 votes

Si je n'inclus pas le -l sur mon système, bc ne fait pas de maths à virgule flottante.

34voto

marvin Points 46

Comme alternative à bc, vous pouvez utiliser awk dans votre script.

Par exemple :

echo "$IMG_WIDTH $IMG2_WIDTH" | awk '{printf "%.2f \n", $1/$2}'

Dans l'exemple ci-dessus, " %.2f " indique à la fonction printf de retourner un nombre à virgule flottante avec deux chiffres après la décimale. J'ai utilisé echo pour introduire les variables en tant que champs puisque l'awk opère correctement sur eux. "$1 " et " $2 " font référence aux premier et deuxième champs entrés dans l'awk.

Et vous pouvez stocker le résultat comme une autre variable en utilisant :

RESULT = `echo ...`

0 votes

Excellent ! Merci. C'est utile pour les environnements embarqués où le bc n'est pas présent. Vous m'avez fait gagner du temps de compilation croisée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X