J'essaie de diviser deux largeurs d'image dans un script Bash, mais bash me donne 0
le résultat:
RESULT=$(($IMG_WIDTH/$IMG2_WIDTH))
J'ai étudié le guide Bash et je sais que je devrais l'utiliser bc
, dans tous les exemples sur Internet qu'ils utilisent bc
. Dans echo
J'ai essayé de mettre la même chose dans mon SCALE
mais il ne fonctionnait pas.
Voici l'exemple que j'ai trouvé dans les tutoriels:
echo "scale=2; ${userinput}" | bc
Comment puis-je demander à Bash de me donner un flotteur 0.5
?
Réponses:
Tu ne peux pas. bash ne fait que des entiers; vous devez déléguer à un outil tel que
bc
.la source
VAR=$(echo "scale=2; $IMG_WIDTH/$IMG2_WIDTH" | bc)
ouVAR=$(bc <<<"scale=2;$IMG_WIDTH/$IMG2_WIDTH")
sans $ (()) (doubles parenthèses); qui est développé par le bash avant d'exécuter la commandetu peux le faire:
MISE À JOUR
20130926
: vous pouvez utiliser:la source
bc -l <<< 'scale=2; 100/3'
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 l'/
opérateur:The scale of the result is the value of the variable scale.
bc <<< 'scale=1; 1*3.00001'
échelle est vraiment 5 pour une raison quelconque, l'bc <<< 'scale=1; 1/3.000001'
échelle est 1. Intéressant, la division par 1 met les choses au clair: l'bc <<< 'scale=1; 1*3.00001/1'
échelle est 1frapper
Comme indiqué par d'autres,
bash
ne prend pas en charge l'arithmétique à virgule flottante, bien que vous puissiez la simuler avec une supercherie décimale fixe, par exemple avec deux décimales:Production:
Voir la réponse de Nilfred pour une approche similaire mais plus concise.
Alternatives
Outre les options mentionnées
bc
etawk
alternatives, il existe également les suivantes:clisp
avec sortie nettoyée:
ou via stdin:
dc
genius cli calculator
ghostscript
gnuplot
jq
Ou:
ksh
lua
ou via stdin:
maxima
avec sortie nettoyée:
nœud
octave
perl
python2
python3
R
avec sortie nettoyée:
rubis
wcalc
Avec sortie nettoyée:
zsh
unités
Avec une sortie compacte:
Autres sources
Stéphane Chazelas a répondu à une question similaire sur Unix.SX.
la source
echo 1/3 | node -p
est court.Améliorant un peu la réponse de marvin:
bc ne vient pas toujours comme paquet installé.
la source
exit
pour l'empêcher de lire à partir de son flux d'entrée. Je suggère également d'utiliser les-v
drapeaux awk 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)}')
RESULT=$(awk '{printf("result= %.2f\n",$1/$2)}' <<<" $IMG_WIDTH $IMG2_WIDTH "
.bc
fait partie de POSIX, il est généralement préinstallé.Vous pouvez utiliser bc par l'
-l
option (la lettre L)la source
-l
sur mon système, bc ne fait pas de calcul en virgule flottante.Comme alternative à bc, vous pouvez utiliser awk dans votre script.
Par exemple:
Dans ce qui précède, "% .2f" indique à la fonction printf de renvoyer un nombre à virgule flottante avec deux chiffres après la décimale. J'ai utilisé l'écho pour diriger les variables sous forme de champs car awk fonctionne correctement sur elles. "$ 1" et "$ 2" font référence aux premier et second champs entrés dans awk.
Et vous pouvez stocker le résultat comme une autre variable en utilisant:
la source
C'est le moment idéal pour essayer zsh, un sur-ensemble (presque) bash, avec de nombreuses fonctionnalités supplémentaires, y compris les mathématiques en virgule flottante. Voici à quoi ressemblerait votre exemple dans zsh:
Cet article peut vous aider: bash - Vaut-il la peine de passer à zsh pour une utilisation décontractée?
la source
Eh bien, avant float était un temps où la logique des décimales fixes était utilisée:
La dernière ligne est un bashim, si vous n'utilisez pas bash, essayez plutôt ce code:
La raison d'être du code est la suivante: multipliez par 100 avant de diviser pour obtenir 2 décimales.
la source
Si vous avez trouvé la variante de votre préférence, vous pouvez également l'encapsuler dans une fonction.
Ici, j'emballe un bashisme dans une fonction div:
Bon mot:
Ou multi-ligne:
Vous avez maintenant la fonction
et l'utiliser comme
MISE À JOUR J'ai ajouté un petit script qui vous fournit les opérations de base avec des nombres à virgule flottante pour bash:
Usage:
Et voici le script:
la source
local _d=${3:-2}
est plus simpleCe n'est pas vraiment une virgule flottante, mais si vous voulez quelque chose qui définit plus d'un résultat en une seule invocation de bc ...
calcule l'aire et le diamètre d'un cercle dont le rayon est donné en $ 1
la source
Il existe des scénarios dans lesquels vous ne pouvez pas utiliser bc car il pourrait tout simplement ne pas être présent, comme dans certaines versions réduites de busybox ou de systèmes intégrés. Dans tous les cas, limiter les dépendances externes est toujours une bonne chose à faire, vous pouvez donc toujours ajouter des zéros au nombre divisé par (numérateur), ce qui revient à multiplier par une puissance de 10 (vous devez choisir une puissance de 10 selon la précision dont vous avez besoin), cela fera de la division un nombre entier. Une fois que vous avez cet entier, traitez-le comme une chaîne et positionnez le point décimal (en le déplaçant de droite à gauche) un nombre de fois égal à la puissance de dix, vous avez multiplié le numérateur par. Il s'agit d'un moyen simple d'obtenir des résultats flottants en utilisant uniquement des nombres entiers.
la source
Bien que vous ne puissiez pas utiliser la division en virgule flottante dans Bash, vous pouvez utiliser la division en virgule fixe. Tout ce que vous devez faire est de multiplier vos entiers par une puissance de 10, puis de diviser la partie entière et d'utiliser une opération modulo pour obtenir la partie fractionnaire. Arrondi au besoin.
la source
je sais que c'est vieux, mais trop tentant. donc, la réponse est: vous ne pouvez pas ... mais vous pouvez en quelque sorte. Essayons ça:
comme ça, vous obtenez 2 chiffres après le point, tronqués (appelez-les arrondis au bas, haha) en bash pur (pas besoin de lancer d'autres processus). bien sûr, si vous n'avez besoin que d'un chiffre après le point, vous multipliez par 10 et faites modulo 10.
ce que cela fait:
piste bonus : la version bc x 1000 a pris 1,8 secondes sur mon ordinateur portable, tandis que la version bash pure a pris 0,016 secondes.
la source
Comment faire des calculs à virgule flottante dans bash:
Au lieu d'utiliser " ici des chaînes " (
<<<
) avec labc
commande, comme le fait l'un des exemples les plus appréciés , voici monbc
exemple de virgule flottante préféré , directement dans laEXAMPLES
section desbc
pages de manuel (voirman bc
les pages de manuel).Avant de commencer, sachez que pour une équation pi est:
pi = 4*atan(1)
.a()
ci-dessous est labc
fonction mathématique pouratan()
.Voici comment stocker le résultat d'un calcul à virgule flottante dans une variable bash - dans ce cas dans une variable appelée
pi
. Notez quescale=10
définit le nombre de chiffres décimaux de précision à 10 dans ce cas. Tous les chiffres décimaux après cet endroit sont tronqués .Maintenant, pour avoir une seule ligne de code qui imprime également la valeur de cette variable, ajoutez simplement la
echo
commande à la fin en tant que commande de suivi, comme suit. Notez la troncature à 10 décimales, comme commandé:Enfin, jetons quelques arrondis. Ici, nous utiliserons la
printf
fonction pour arrondir à 4 décimales. Notez que les3.14159...
tours maintenant3.1416
. Puisque nous arrondissons, nous n'avons plus besoin d'utiliserscale=10
pour tronquer à 10 décimales, nous allons donc simplement supprimer cette partie. Voici la solution finale:Voici une autre très bonne application et démonstration des techniques ci-dessus: mesurer et imprimer le temps d'exécution.
Notez que la valeur
dt_min
est arrondie de0.01666666666...
à0.017
:En relation:
la source
Utilisez calc. C'est l'exemple le plus simple que j'ai trouvé:
la source
Pour ceux qui essaient de calculer des pourcentages avec la réponse acceptée, mais qui perdent en précision:
Si vous exécutez ceci:
Vous obtenez
99.00
seulement, ce qui perd de la précision.Si vous l'exécutez de cette façon:
Maintenant vous obtenez
99.99
.Parce que vous ne mettez à l'échelle qu'au moment de l'impression.
Se référer ici
la source
** Mathématiques à virgule flottante sécurisées pour les injections dans bash / shell **
Remarque: L'objectif de cette réponse est de fournir des idées pour une solution sécurisée par injection pour effectuer des mathématiques dans bash (ou d'autres shells). Bien sûr, la même chose peut être utilisée, avec des ajustements mineurs pour effectuer un traitement avancé des chaînes, etc.
La plupart des solutions présentées ont été construites à la volée, à l'aide de données externes (variables, fichiers, ligne de commande, variables d'environnement). L'entrée externe peut être utilisée pour injecter du code malveillant dans le moteur, beaucoup d'entre eux
Ci-dessous est une comparaison sur l'utilisation des différents langages pour effectuer des calculs mathématiques de base, où le résultat en virgule flottante. Il calcule A + B * 0,1 (en virgule flottante).
Toutes les solutions tentent d'éviter de créer des scriptlets dynamiques, qui sont extrêmement difficiles à maintenir. À la place, ils utilisent un programme statique et transmettent les paramètres à la variable désignée. Ils géreront en toute sécurité les paramètres avec des caractères spéciaux - réduisant ainsi la possibilité d'injection de code. L'exception est «BC» qui ne fournit pas de fonctionnalité d'entrée / sortie
L'exception est 'bc', qui ne fournit aucune entrée / sortie, toutes les données proviennent de programmes dans stdin, et toutes les sorties vont à stdout. Tous les calculs s'exécutent dans un sandbox, ce qui ne permet pas d'effet secondaire (ouverture de fichiers, etc.). En théorie, l'injection est sûre par conception!
la source
python3 -c 'import sys ; *a, = map(float, sys.argv[1:]) ; print(a[0] + a[1]*0.1 + a[2])' "$A" "$B"
"4200.0" ==> 4205.63voici la commande awk: -F = séparateur de champ == +
la source