[gelöst] Kommazahl groesser/kleiner als - in der Shell?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
tomi89
Beiträge: 250
Registriert: 21.08.2014 00:21:52

[gelöst] Kommazahl groesser/kleiner als - in der Shell?

Beitrag von tomi89 » 07.12.2018 10:46:49

Hallo Forum!

Kann man in einer Shell auch Kommazahlen zwischen grösse unterscheiden?

Also quasi so:

Code: Alles auswählen

if [ $KOMMAZAHLA -gt $KOMMAZAHLB ]; then ...
Nur leider funktioniert dies nur mit ganzen Zahlen.

Aber ich muss es schon mit Kommazahlen lösen.

Aber wie stellt man so etwas bitte an?
Zuletzt geändert von tomi89 am 07.12.2018 12:40:40, insgesamt 1-mal geändert.

Benutzeravatar
rodney
Beiträge: 82
Registriert: 09.12.2016 04:15:59
Lizenz eigener Beiträge: MIT Lizenz

Re: Kommazahl groesser/kleiner als - in der Shell?

Beitrag von rodney » 07.12.2018 10:58:22

Am einfachsten waere die Verwendung von Debianbc. Rein in der Shell waere etwas umstaendlicher:

1. Anzahl der maximalen Nachkommastellen der zu vergleichenden Zahlen berechnen
2. Beide Zahlen mit 10 ^ Nachkommastellenanzahl multiplizieren
3. Die Ergebnisse vergleichen
I don't like poofy coffee... give me Columbian Supremo. --Izchak

tomi89
Beiträge: 250
Registriert: 21.08.2014 00:21:52

Re: Kommazahl groesser/kleiner als - in der Shell?

Beitrag von tomi89 » 07.12.2018 11:11:08

Danke für die schnelle Antwort.

Wenn ich es richtig verstanden habe rundet BC auf.

Das Ergebnis muss allerdings bis zur letzten Nachkommastelle unverfälscht bleiben.
Zuletzt geändert von tomi89 am 07.12.2018 11:16:31, insgesamt 1-mal geändert.

eggy
Beiträge: 1551
Registriert: 10.05.2008 11:23:50

Re: Kommazahl groesser/kleiner als - in der Shell?

Beitrag von eggy » 07.12.2018 11:15:26

Die manpage von bc sagt zum Zahlenformat folgendes:
NUMBERS
The most basic element in bc is the number. Numbers are arbitrary precision numbers. This precision is both in the integer part and the fractional part. All numbers are represented internally in decimal and all computation is done in decimal. (This version truncates results from divide and multiply operations.) There are two attributes of numbers, the length and the scale. The length is the total number of decimal digits used by bc to represent a number and the scale is the total number of decimal digits after the decimal point. For example:
.000001 has a length of 6 and scale of 6.
1935.000 has a length of 7 and a scale of 3.

Huo
Beiträge: 65
Registriert: 26.11.2017 14:03:31

Re: Kommazahl groesser/kleiner als - in der Shell?

Beitrag von Huo » 07.12.2018 11:27:04

Um bc mit Fließkommazahlen rechnen zu lassen, musst Du die Option -l verwenden:

Code: Alles auswählen

$ bc -l <<< "2.3 + 7.8"
10.1
$ bc -l <<< "2.3 > 7.8"
0
$ bc -l <<< "2.3 < 7.8"
1

uname
Beiträge: 9571
Registriert: 03.06.2008 09:33:02

Re: Kommazahl groesser/kleiner als - in der Shell?

Beitrag von uname » 07.12.2018 12:08:17

Vielleicht so:

Code: Alles auswählen

if (( $(echo "$KOMMAZAHLA > $KOMMAZAHLB" |bc -l) )); then
  …
fi
https://stackoverflow.com/questions/865 ... rs-in-bash

tomi89
Beiträge: 250
Registriert: 21.08.2014 00:21:52

Re: Kommazahl groesser/kleiner als - in der Shell?

Beitrag von tomi89 » 07.12.2018 12:40:13

Danke für die Antworten.

Ich habe es jetzt so gelöst:

Code: Alles auswählen

AAA="128.2800"
BBB="128.2900"
if [ x"$(echo "scale=4; $AAA < $BBB" | bc -l)" = x1 ]; then
echo "ok"
fi

wanne
Moderator
Beiträge: 5618
Registriert: 24.05.2010 12:39:42

Re: [gelöst] Kommazahl groesser/kleiner als - in der Shell?

Beitrag von wanne » 08.12.2018 11:02:43

Um bc mit Fließkommazahlen rechnen zu lassen, musst Du die Option -l verwenden:
Nein. bc rechnet mit Festkommazahlen. Das ist das dicke Feature von bc gegenüber fast allen anderen tools. Defakto ist das in 99% eher nicht das was du haben willst. Es ist aber eben deutlich einfacher vorhersehbar, was passiert. Du kannst explizit angeben wieviele Nachkommastellen (im 10er System) du haben willst. Ich würde eher calc aus Debianapcalc bevorzugen. Schwerer zu beschreiben, was es macht, aber im Normalfall das was du willst. (Fließkommazahlen)

Das ist doppelt gemoppelt. Oder eigentlich dreifach:

Code: Alles auswählen

128.2800
Damit, dass du die vier Nachkommastellen angibst nimmt bc automatisch an, dass du mit vier Nachkommastellen rechnen willst.

Code: Alles auswählen

bc -l
Setz das ganze dann auf 20 hoch.

Code: Alles auswählen

scale=4
Damit setzt du es dann wieder zurück auf 4 Nachkommastellen.
Schönere Variante mit bc:

Code: Alles auswählen

AAA="128.2800"
BBB="128.2900"
if [ $(echo "$BBB > $AAA" | bc) -eq 1 ]; then
echo "ok"
fi
Oder:

Code: Alles auswählen

AAA="128.28"
BBB="128.29"
if [ $(echo "scale=4; $BBB > $AAA" | bc) -eq 1 ]; then
echo "ok"
fi
Im Prinzip auch (zwei Nachkommastellen reichen ja)

Code: Alles auswählen

AAA="128.28"
BBB="128.29"
if [ $(echo "$BBB > $AAA" | bc) -eq 1 ]; then
echo "ok"
fi
rot: Moderator wanne spricht, default: User wanne spricht.

RobertDebiannutzer
Beiträge: 259
Registriert: 16.06.2017 09:52:36

Re: [gelöst] Kommazahl groesser/kleiner als - in der Shell?

Beitrag von RobertDebiannutzer » 08.12.2018 11:41:31

Ohne bc gings auch. Einfach Zahlen vor dem Komma vergleichen und wenn gleich, Zahlen hinterm Komma vergleichen.

Ungenügend getesteter Vorschlag:

Code: Alles auswählen

$ a=120.123
$ b=120.456
$ if [ ${a%\.*} -eq ${b%\.*} ]; then n=$((${a#*\.}-${b#*\.})); if [ $n -gt 0 ]; then echo "0.$n"; else echo "-0.${n#-}"; fi; else echo $((${a%\.*}-${b%\.*})); fi
-0.333
Zur Verdeutlichung:

Code: Alles auswählen

$ echo ${a%\.*} ${a#*\.} ${b%\.*} ${b#*\.}
120 123 120 456
OK, ist jetzt vielleicht nicht das Lesbarste...

EDIT:
Nö, geht leider doch nicht so einfach. Man müsste erst noch mit den Nullen hantieren, denn:

Code: Alles auswählen

$ a=120.0123
$ b=120.00456
$ if [ ${a%\.*} -eq ${b%\.*} ]; then n=$((${a#*\.}-${b#*\.})); if [ $n -gt 0 ]; then echo "0.$n"; else echo "-0.${n#-}"; fi; else echo $((${a%\.*}-${b%\.*})); fi
-0.219
Das wird dann doch etwas kompliziert, wenn man auch bc verwenden kann...

Benutzeravatar
detix
Beiträge: 1419
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: [gelöst] Kommazahl groesser/kleiner als - in der Shell?

Beitrag von detix » 08.12.2018 22:20:45

Nur mal nachgefragt:
die Lösung von uname war ja schon perfekt und funktioniert, auch die von wanne,
...nur warum muss bei wannes Post noch auf Gleichheit „-eq 1” geprüft werden?
bc kann dies doch selbst, nicht aber bei if..., oder ist es mit den bc Ausgaben hier entgegen den Standards umgekehrt (1=ok, 0=falsch)?

Code: Alles auswählen

AAA="128.2800"
BBB="128.2900" # BBB ist größer als AAA
echo "$BBB > $AAA" | bc # aber Ausgabe ist 1, also Fehler und angeblich falsch
1
BBB="128.2799" # BBB ist kleiner als AAA
echo "$BBB > $AAA" | bc # aber Ausgabe ist 0, also richtig und angeblich kein Fehler
0
Wo ist mein Denkfehler? Lügt bc hier oder hält es sich nicht an die Standards?
Gruß an alle Debianer

RobertDebiannutzer
Beiträge: 259
Registriert: 16.06.2017 09:52:36

Re: [gelöst] Kommazahl groesser/kleiner als - in der Shell?

Beitrag von RobertDebiannutzer » 08.12.2018 22:28:27

Ich glaube, Du verwechselt den Rückgabewert von Programmen (0=kein Fehler, 1=Fehler) und wahr und falsch. In C ist ja auch 0 falsch und alles, was nicht 0 ist, wahr.
Ich habe mal was für bash ausprobiert:

Code: Alles auswählen

$ while ((0)); do echo hallo; done
$ while ((1)); do echo hallo; done
hallo
hallo
hallo
hallo
hallo
hallo
[…]

Benutzeravatar
detix
Beiträge: 1419
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: [gelöst] Kommazahl groesser/kleiner als - in der Shell?

Beitrag von detix » 08.12.2018 22:42:33

bc gibt mir den Rückgabewert, nur eben falsch herum aus meiner Sicht...
Gruß an alle Debianer

wanne
Moderator
Beiträge: 5618
Registriert: 24.05.2010 12:39:42

Re: [gelöst] Kommazahl groesser/kleiner als - in der Shell?

Beitrag von wanne » 09.12.2018 03:35:35

Grundsätzlich ein übliches UNIX Programm kann irgend bytes in eine Datei schreiben. (Dabei sind stdout und stderr, die Dateien, die dir automatisch auf der Konsole angezeigt werden.) Ein Signal an einen anderen Prozess Senden und muss immer beim beenden eine ganze Zahl zurück geben. (Es gibt verschiedenste Arten von Dateien und noch ein paar obskure andere Sachen.) Aber wir belassen es mal bei der Vereinfachten Form.
bc gibt mir den Rückgabewert, nur eben falsch herum aus meiner Sicht...
bc gibt bei korrekter Syntax immer den Rückgabewert 0. Das Ergebnis schreibt es nach stdout. Das ist aber kein Rückgabewert.
Zur Verdeutlichung: Der Rückgabewert ist eine ganze Zahl und du fragst sie du über $? ab.

Code: Alles auswählen

$ [ 5 -le 3 ] > /dev/null ; echo $?
> 1
$ [ 3 -le 5 ] > /dev/null ; echo $?
> 0
Aber:

Code: Alles auswählen

$ echo "5 > 3" | bc  > /dev/null ; echo $?
> 0
$ echo "0 > 5" | bc  > /dev/null ; echo $?
> 0
stdout ist ein stream von Bytes siehst du automatisch:
$ [ 5 > 3 ]
$ echo "3 > 5" | bc
> 0
Wie du siehst sieht man bei test bzw [ ] nichts. bc sagt aber 0.
echo $? wandelt die Zahl des Rückgabewerts in die Lesbare Zeichen um.
Umgekehrt kommen wir zur frage:
nur warum muss bei wannes Post noch auf Gleichheit „-eq 1” geprüft werden?

Code: Alles auswählen

test ... -eq 1
wandelt das Zeichen 1 in den Rückgabewert 0 um (Für alle anderen Bytes die als eine Zahl gelesen werden können in 1, und alles andere in 2)
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
detix
Beiträge: 1419
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: [gelöst] Kommazahl groesser/kleiner als - in der Shell?

Beitrag von detix » 10.12.2018 20:05:44

Eigentlich sollte es mir schon selbst klar sein :oops: :
0 und 1 von bc ist nicht vergleichbar mit true oder false, vielen Dank für eure Erklärungen.
Gruß an alle Debianer

Antworten