Vous pouvez vérifier séparément les parties entières et fractionnaires:
#!/bin/bash
min=12.45
val=12.35
if (( ${val%%.*} < ${min%%.*} || ( ${val%%.*} == ${min%%.*} && ${val##*.} < ${min##*.} ) )) ; then
min=$val
fi
echo $min
Comme le dit Fered dans les commentaires, cela ne fonctionne que si les deux nombres ont des parties fractionnaires et que les deux parties fractionnaires ont le même nombre de chiffres. Voici une version qui fonctionne pour entier ou fractionnaire et tout opérateur bash:
#!/bin/bash
shopt -s extglob
fcomp() {
local oldIFS="$IFS" op=$2 x y digitx digity
IFS='.' x=( ${1##+([0]|[-]|[+])}) y=( ${3##+([0]|[-]|[+])}) IFS="$oldIFS"
while [[ "${x[1]}${y[1]}" =~ [^0] ]]; do
digitx=${x[1]:0:1} digity=${y[1]:0:1}
(( x[0] = x[0] * 10 + ${digitx:-0} , y[0] = y[0] * 10 + ${digity:-0} ))
x[1]=${x[1]:1} y[1]=${y[1]:1}
done
[[ ${1:0:1} == '-' ]] && (( x[0] *= -1 ))
[[ ${3:0:1} == '-' ]] && (( y[0] *= -1 ))
(( ${x:-0} $op ${y:-0} ))
}
for op in '==' '!=' '>' '<' '<=' '>='; do
fcomp $1 $op $2 && echo "$1 $op $2"
done
0.5
et0.06
). Vous feriez mieux d'utiliser un outil qui comprend déjà la notation décimale.1.00000000000000000000000001
c'est plus grand que2
.Bash ne comprend pas l'arithmétique à virgule flottante. Il traite les nombres contenant un point décimal comme des chaînes.
Utilisez plutôt awk ou bc.
Si vous avez l'intention de faire beaucoup d'opérations mathématiques, il est probablement préférable de s'appuyer sur python ou perl.
la source
Vous pouvez utiliser le paquet num-utils pour des manipulations simples ...
Pour des mathématiques plus sérieuses, voir ce lien ... Il décrit plusieurs options, par exemple.
Un exemple de
numprocess
Voici un
bash
hack ... Il ajoute des 0 en tête à l'entier pour donner une signification à une comparaison de gauche à droite. Ce morceau de code particulier nécessite que min et val aient en fait un point décimal et au moins un chiffre décimal.sortie:
la source
Pour des calculs simples sur des nombres à virgule flottante (+ - * / et des comparaisons), vous pouvez utiliser awk.
Ou, si vous avez ksh93 ou zsh (pas bash), vous pouvez utiliser l'arithmétique intégrée de votre shell, qui prend en charge les nombres à virgule flottante.
Pour des calculs en virgule flottante plus avancés, recherchez bc . Il fonctionne en fait sur les nombres de points fixes à précision arbitraire.
Pour travailler sur des tableaux de nombres, recherchez R ( exemple ).
la source
Utiliser le tri numérique
La commande
sort
a une option-g
(--general-numeric-sort
) qui peut être utilisée pour des comparaisons sur<
«moins de» ou>
«plus grand que» en trouvant le minimum ou le maximum.Ces exemples trouvent le minimum:
Prend en charge la notation électronique
Il fonctionne avec une notation assez générale des nombres à virgule flottante, comme avec la notation E
Notez le
E-10
, faisant le premier nombre0.000000001245
, en effet inférieur à10.35
.Peut se comparer à l'infini
La norme à virgule flottante, IEEE754 , définit certaines valeurs spéciales. Pour ces comparaisons, les plus intéressantes sont
INF
pour l'infini. Il y a aussi l'infini négatif; Les deux sont des valeurs bien définies dans la norme.Pour trouver l'utilisation maximale
sort -gr
au lieu desort -g
, inverser l'ordre de tri:Opération de comparaison
Pour implémenter la
<
comparaison ("moins de"), afin qu'elle puisse être utilisée dansif
etc, comparez le minimum à l'une des valeurs. Si le minimum est égal à la valeur, comparé au texte , il est inférieur à l'autre valeur:la source
a == min(a, b)
est la même quea <= b
. Il convient de noter que cela ne vérifie pas strictement moins que cela. Si vous voulez le faire, vous devez vérifiera == min(a, b) && a != max(a, b)
, en d'autres termesa <= b and not a >= b
Utilisez simplement
ksh
(ksh93
précisément) ouzsh
, qui prennent tous les deux en charge l'arithmétique en virgule flottante:Edit: Désolé, j'ai raté
ksh93
a déjà été suggéré. Garder ma réponse juste pour clarifier le script publié dans la question d'ouverture peut être utilisé sans changement en dehors du commutateur shell.Edit2: Notez que
ksh93
le contenu de la variable doit être cohérent avec votre environnement local, c'est-à-dire avec un environnement local français, une virgule au lieu d'un point doit être utilisée:Une solution plus robuste consiste à définir les paramètres régionaux au début du script pour vous assurer qu'il fonctionnera indépendamment des paramètres régionaux de l'utilisateur:
la source
.
(donc pas dans la moitié du monde où se trouve le séparateur décimal,
).zsh
n'a pas ce problème.LC_ALL
, cela signifie également que les nombres ne seront pas affichés (ou saisis) dans le format préféré de l'utilisateur. Voir unix.stackexchange.com/questions/87745/what-does-lc-all-c-do/… pour une approche potentiellement meilleure..
toute façon.Cela utilise la
dc
calculatrice pours
déchirer la valeur de$min
in registera
etd
répliquer la valeur de en$val
haut de sa pile d'exécution principale. Ill
répertorie ensuite le contenu dea
sur le haut de la pile, auquel cas il ressemble à:Le fait
<
apparaître les deux premières entrées de la pile et les compare. La pile ressemble alors à:Si l'entrée supérieure était inférieure à la seconde en haut, elle pousse le contenu de
a
vers le haut, de sorte que la pile ressemble à:Sinon, cela ne fait rien et la pile ressemble toujours à:
Ensuite, il
p
imprime simplement l'entrée de la pile supérieure.Donc pour votre problème:
Mais:
la source
Pourquoi ne pas utiliser vieux, bon
expr
?Exemple de syntaxe:
Pour les expressions vraies , le code de sortie expr est 0, avec la chaîne «1» envoyée à stdout. Inverser pour les fausses expressions.
J'ai vérifié cela avec GNU et FreeBSD 8 expr.
la source
expr 1.09 '<' -1.1
imprimera1
et quittera avec0
(succès).Pour vérifier si deux nombres (éventuellement fractionnaires) sont en ordre,
sort
est (raisonnablement) portable:Cependant, si vous voulez réellement mettre à jour une valeur minimale, vous n'avez pas besoin d'un
if
. Triez les chiffres et utilisez toujours le premier (le moins):la source
Habituellement, je fais des choses similaires avec du code python intégré:
la source
la source