Chcę porównać dwie liczby zmiennoprzecinkowe w skrypcie powłoki. Poniższy kod nie działa:
#!/bin/bash
min=12.45
val=10.35
if (( $val < $min )) ; then
min=$val
fi
echo $min
shell
shell-script
arithmetic
RIchard Williams
źródło
źródło
0.5
i0.06
). Lepiej użyj narzędzia, które już rozumie zapis dziesiętny.1.00000000000000000000000001
jest większe niż2
.Bash nie rozumie arytmetyki zmiennoprzecinkowej. Liczby zawierające przecinek dziesiętny traktuje jak ciągi znaków.
Zamiast tego użyj awk lub bc.
Jeśli zamierzasz wykonywać wiele operacji matematycznych, prawdopodobnie lepiej polegać na Pythonie lub Perlu.
źródło
Możesz użyć pakietu num-utils do prostych manipulacji ...
Aby uzyskać więcej informacji na temat matematyki, zobacz ten link ... Opisuje kilka opcji, np.
Przykład
numprocess
Oto
bash
hack ... Dodaje wiodące zera do liczby całkowitej, aby sensowne było porównywanie ciągów od lewej do prawej. Ten konkretny fragment kodu wymaga, aby zarówno min, jak i val faktycznie miały kropkę dziesiętną i co najmniej jedną cyfrę dziesiętną.wydajność:
źródło
Do prostych obliczeń na liczbach zmiennoprzecinkowych (+ - * / i porównaniach) możesz użyć awk.
Lub, jeśli masz ksh93 lub zsh (nie bash), możesz użyć wbudowanej arytmetyki powłoki, która obsługuje liczby zmiennoprzecinkowe.
Aby uzyskać bardziej zaawansowane obliczenia zmiennoprzecinkowe, wyszukaj temat bc . W rzeczywistości działa na liczbach punktów o dowolnej dokładności.
Aby pracować na tablicach liczb, poszukaj R ( przykład ).
źródło
Użyj sortowania numerycznego
Polecenie
sort
ma opcję-g
(--general-numeric-sort
), której można użyć do porównań<
„mniej niż” lub>
„większy niż” poprzez znalezienie minimum lub maksimum.Te przykłady znajdują minimum:
Obsługuje notację elektroniczną
Działa z dość ogólną notacją liczb zmiennoprzecinkowych, jak w przypadku notacji E.
Zwróć uwagę na to
E-10
, że pierwsza liczba jest0.000000001245
rzeczywiście mniejsza niż10.35
.Można porównać do nieskończoności
Standard zmiennoprzecinkowy, IEEE754 , definiuje niektóre wartości specjalne. Dla tych porównań interesujące są
INF
dla nieskończoności. Istnieje również ujemna nieskończoność; Obie są dobrze zdefiniowanymi wartościami w standardzie.Aby znaleźć maksymalne wykorzystanie
sort -gr
zamiastsort -g
, odwracanie kolejności sortowania:Operacja porównania
Aby wdrożyć porównanie
<
(„mniejsze niż”), aby można go było stosować wif
itp., Porównaj minimum z jedną z wartości. Jeśli minimum jest równe wartości, w porównaniu z tekstem , jest mniejsze niż inna wartość:źródło
a == min(a, b)
jest takie samo jaka <= b
. Warto zauważyć, że nie sprawdza to dokładnie mniej niż chociaż. Jeśli chcesz to zrobić, musisz sprawdzića == min(a, b) && a != max(a, b)
, innymi słowya <= b and not a >= b
Wystarczy użyć
ksh
(ksh93
dokładnie) lubzsh
, które oba natywnie obsługują arytmetykę zmiennoprzecinkową:Edycja: Przepraszam, że tęskniłem
ksh93
już zaproponowano. Zachowując moją odpowiedź, aby wyjaśnić, skrypt zamieszczony w pytaniu otwierającym może być używany bez żadnych zmian poza przełącznikiem powłoki.Edycja2: Zauważ, że
ksh93
wymaga , aby zawartość zmiennej była zgodna z twoimi ustawieniami regionalnymi, tj. W przypadku francuskich ustawień regionalnych, zamiast kropki należy użyć przecinka:Bardziej niezawodnym rozwiązaniem jest ustawienie ustawień regionalnych na początku skryptu, aby upewnić się, że będzie on działał niezależnie od ustawień regionalnych użytkownika:
źródło
.
(więc nie w połowie świata, w którym znajduje się separator dziesiętny,
).zsh
nie ma tego problemu.LC_ALL
, co oznacza również, że liczby nie będą wyświetlane (lub wprowadzane) w preferowanym przez użytkownika formacie. Potencjalnie lepsze podejście można znaleźć na stronie unix.stackexchange.com/questions/87745/what-does-lc-all-c-do/ ....
tak.To używa
dc
kalkulatora do zerwanias
wartości$min
w rejestrzea
id
umieszcza wartość$val
na szczycie głównego stosu wykonawczego. Następniel
umieszcza zawartośća
na górze stosu, w którym to momencie wygląda następująco:<
Wyskakuje szczycie dwa wpisy od stosu i porównuje je. Tak więc stos wygląda następująco:Jeśli górna pozycja była mniejsza niż druga od góry, wypycha zawartość
a
na górę, więc stos wygląda następująco:W przeciwnym razie nic nie robi, a stos nadal wygląda:
Następnie po prostu
p
sprawdza, czy wpis najwyższego stosu jest zaznaczony.Więc dla twojego problemu:
Ale:
źródło
Dlaczego nie użyć starego, dobrego
expr
?Przykładowa składnia:
Dla prawdziwych wyrażeń kod wyjścia expr wynosi 0, a ciąg „1” jest wysyłany do standardowego wyjścia. Odwróć dla fałszywych wyrażeń.
Sprawdziłem to z GNU i FreeBSD 8 expr.
źródło
expr 1.09 '<' -1.1
wydrukuje1
i wyjdzie za pomocą0
(sukces).Aby sprawdzić, czy dwie (ewentualnie ułamkowe) liczby są w porządku,
sort
jest (w miarę rozsądnie) przenośne:Jeśli jednak chcesz aktualizować minimalną wartość, nie potrzebujesz
if
. Sortuj liczby i zawsze używaj pierwszego (najmniejszego):źródło
Zwykle robię podobne rzeczy z osadzonym kodem python:
źródło
źródło