Ich möchte zwei Gleitkommazahlen in einem Shell-Skript vergleichen. Der folgende Code funktioniert nicht:
#!/bin/bash
min=12.45
val=10.35
if (( $val < $min )) ; then
min=$val
fi
echo $min
shell
shell-script
arithmetic
Richard Williams
quelle
quelle
0.5
und0.06
). Sie sollten ein Tool verwenden, das die Dezimalschreibweise bereits versteht.1.00000000000000000000000001
größer ist als2
.Bash versteht keine Gleitkomma-Arithmetik. Zahlen, die ein Dezimalzeichen enthalten, werden als Zeichenfolgen behandelt.
Verwenden Sie stattdessen awk oder bc.
Wenn Sie vorhaben, viele mathematische Operationen durchzuführen, ist es wahrscheinlich besser, sich auf Python oder Perl zu verlassen.
quelle
Sie können package num-utils für einfache Manipulationen verwenden ...
Weitere Informationen zu Mathematik finden Sie unter diesem Link. Hier werden verschiedene Optionen beschrieben, z.
Ein Beispiel für
numprocess
Hier ist ein
bash
Hack ... Er fügt der Ganzzahl führende Nullen hinzu, um einen String-Vergleich von links nach rechts aussagekräftig zu machen. Für diesen speziellen Code ist es erforderlich, dass sowohl min als auch val tatsächlich einen Dezimalpunkt und mindestens eine Dezimalstelle haben.Ausgabe:
quelle
Für einfache Berechnungen von Gleitkommazahlen (+ - * / und Vergleiche) können Sie awk verwenden.
Wenn Sie ksh93 oder zsh (nicht bash) haben, können Sie die integrierte Arithmetik Ihrer Shell verwenden, die Gleitkommazahlen unterstützt.
Weitere Informationen zu Gleitkommaberechnungen finden Sie unter bc . Es funktioniert tatsächlich mit Fixpunktzahlen mit beliebiger Genauigkeit.
Wenn Sie mit Zahlentabellen arbeiten möchten, schlagen Sie R nach ( Beispiel ).
quelle
Verwenden Sie die numerische Sortierung
Der Befehl
sort
hat eine Option-g
(--general-numeric-sort
), die für Vergleiche mit<
"kleiner als" oder "kleiner als" verwendet werden kann>
"größer als" verwendet werden kann, indem das Minimum oder Maximum ermittelt wird.Diese Beispiele finden das Minimum:
Unterstützt E-Notation
Es funktioniert mit einer ziemlich allgemeinen Notation von Gleitkommazahlen, wie bei der E-Notation
Beachten Sie
E-10
, dass die erste Zahl0.000000001245
tatsächlich kleiner ist als10.35
.Kann mit unendlich vergleichen
Der Gleitkomma-Standard IEEE754 definiert einige spezielle Werte. Für diese Vergleiche sind die interessantesten
INF
für die Unendlichkeit. Es gibt auch die negative Unendlichkeit; Beides sind im Standard genau definierte Werte.Um die maximale Verwendung finden
sort -gr
stattsort -g
, die Sortierreihenfolge umzukehren:Vergleichsoperation
Um den
<
Vergleich ("kleiner als") zu implementieren , damit er inif
etc verwendet werden kann, vergleichen Sie das Minimum mit einem der Werte. Wenn das Minimum dem als Text verglichenen Wert entspricht, ist es kleiner als der andere Wert:quelle
a == min(a, b)
das Gleiche ist wiea <= b
. Es ist erwähnenswert, dass dies nicht unbedingt weniger prüft als wenn. Wenn Sie das tun möchten, müssen Siea == min(a, b) && a != max(a, b)
in anderena <= b and not a >= b
Verwenden Sie einfach
ksh
(ksh93
genau) oderzsh
, die beide Fließkomma-Arithmetiken unterstützen:Edit: Sorry, ich habe vermisst,
ksh93
wurde bereits vorgeschlagen. Wenn ich meine Antwort behalte, um das in der Eröffnungsfrage veröffentlichte Skript zu verdeutlichen, kann es ohne Änderung außerhalb des Shell-Switches verwendet werden.Edit2: Beachten Sie,
ksh93
dass der Inhalt der Variablen mit Ihrem Gebietsschema übereinstimmen muss, dh bei einem französischen Gebietsschema muss ein Komma anstelle eines Punkts verwendet werden:Eine robustere Lösung besteht darin, das Gebietsschema am Anfang des Skripts festzulegen, um sicherzustellen, dass es unabhängig vom Gebietsschema des Benutzers funktioniert:
quelle
.
(also nicht in der halben Welt, in der sich das Dezimaltrennzeichen befindet,
).zsh
hat dieses Problem nicht.LC_ALL
bedeutet auch, dass Zahlen nicht im vom Benutzer bevorzugten Format angezeigt (oder eingegeben) werden. Eine möglicherweise bessere Vorgehensweise finden Sie unter unix.stackexchange.com/questions/87745/what-does-lc-all-c-do/… ..
sowieso ist.Das benutzt den
dc
Rechner, ums
den Wert für$min
im Register zu speicherna
undd
kopiert den Wert von$val
oben auf seinen Hauptausführungsstapel. Dann wirdl
der Inhalt vona
oben auf den Stapel gelegt und sieht dann so aus:Die
<
beiden obersten Einträge werden vom Stapel entfernt und verglichen. Der Stack sieht dann so aus:Wenn der oberste Eintrag kleiner als der zweithöchste war, wird der Inhalt von nach oben geschoben
a
, sodass der Stapel wie folgt aussieht:Sonst macht es nichts und der Stack sieht immer noch so aus:
Dann wird nur
p
der oberste Stapeleintrag gedruckt.Also für dein Problem:
Aber:
quelle
Warum nicht alt, gut
expr
?Beispielsyntax:
Bei wahren Ausdrücken ist der Exit-Code expr 0, und die Zeichenfolge '1' wird an stdout gesendet. Reverse für falsche Ausdrücke.
Ich habe dies mit GNU und FreeBSD 8 expr überprüft.
quelle
expr 1.09 '<' -1.1
wird gedruckt1
und beendet mit0
(Erfolg).Um zu überprüfen, ob zwei (möglicherweise gebrochene) Zahlen in Ordnung sind,
sort
ist (vernünftigerweise) Folgendes übertragbar:Wenn Sie jedoch tatsächlich einen Mindestwert aktualisieren möchten, benötigen Sie keinen
if
. Sortieren Sie die Zahlen und verwenden Sie immer die erste (kleinste):quelle
Normalerweise mache ich ähnliche Dinge mit eingebettetem Python-Code:
quelle
quelle