Bitte warten...

Bash: Zahlen

Bash beherrscht von Hause aus nur Ganzzahl-Operationen im Zahlenraum von –263 bis 263 – 1
(int64_t); Für Fließkomma-Operationen und größere Zahlen müssen externe Programme eingebunden werden. Exponentialschreibweisen wie 1e9 bzw. 1E9 werden nicht unterstützt.

Folgende elementare arithmetische Operatoren werden unterstützt:

Code kopieren
a=100
b=25
c=$(($a+$b))     # Addition in Schreibweise A (POSIX-kompatibel)
((d = $a - $b))  # Subtraktion in Schreibweise B

echo "100 + 25 =" $c
echo "100 - 25 =" $d
echo "100 * 25 =" $(($a * $b))  # Plutimikation
echo "100 / 25 =" $((a / b))    # Division
echo "2 ** 8 =" $((2 ** 8))     # Potenzierung
echo "11 % 3 =" $((11 % 3))     # Modulo (= 11 - 3 * int(11 / 3))

# Alternative Schreibweisen:
expr 100 + 25
expr 100 - 25
expr $a \* $b
expr $a / $b

Bei arithmetischen Operationen darf der $-Operator vor Variablennamen weggelassen werden (Zeile 9).

Für die Grundrechenarten existieren folgende Kurzschreibweisen:

Code kopieren
((a += 2))  # gleich ((a = $a + 2))
((b -= 2))  # gleich ((b = $b - 2))
((c *= 2))  # gleich ((c = $c * 2))
((d /= 2))  # gleich ((d = $d / 2))

echo "100 + 2 =" $a
echo "25 - 2 =" $b
echo "125 * 2 =" $c
echo "75 / 2 =" $d

Inkrementierung und Dekrementierung

Mit den Operatoren ++ sowie -- können Zahlenwerte um 1 erhöht bzw. vermindert werden. Stehen die Operatoren vor der Variablen, so wird die Wertänderung zuerst ausgeführt und dann an die Anweisung (hier: echo) übergeben. Stehen die Operatoren nach der Variablen, wird die Wertänderung erst ausgeführt, nachdem der Wert an die Anweisung übergeben wurde.

Code kopieren
a=100
b=25

echo $((++a))
echo $((--b))
echo $a
echo $b
echo
echo $((a++))
echo $((b--))
echo $a
echo $b

Zahlenraum bestimmen

Der verfügbare Zahlenraum lässt sich folgendermaßen ermitteln:

Code kopieren
((a = 2 ** 63 - 1))
echo $a  # 9223372036854775807
((a++))
echo $a  # -9223372036854775808 = -2 ** 63

Dies hat zur Konsequenz, dass Zahlen kleiner als –263 oder größer als 263 – 1 stillschweigend zu einem Überlauf führen, was durch eine Ausnahmebehandlung abgefangen werden sollte.

Zufallszahlen

Mit der Funktion RANDOM lassen sich pseudozufällige Zahlen im Bereich von 0 bis 32767 (2⁰ bis 2¹⁵ – 1) erzeugen. Diese können dann mit gewöhnlicher Arithmetik in einen gewünschten Bereich gebracht werden. Siehe auch stackoverflow.com.

Code kopieren
echo $RANDOM  # Zufallszahl von 0 bis 32767
echo $((RANDOM % 100))  # Zufallszahl von 0 bis 99
echo $((10 + RANDOM % 15))  # Zufallszahl von 10 bis 24

Berechnungen mithilfe von bc

Mithilfe des Programms bc (basic calculator) können weitergehende mathematische Berechnungen durchgeführt werden, als dies mit den oben beschriebenen Optionen möglich ist.

Zunächst einmal ein Beispiel für den Aufruf von bc (hier mit Fließkommazahlen):

Code kopieren
a=$(echo 5.41 + 4.23 | bc)
echo $a  # 9.64

Dieser Aufruf wird wie folgt gelesen: Das Argument 5.41 + 4.23 enthält eine Operation, die mit dem Kommando echo über eine Pipe (repräsentiert durch das Zeichen |) an das Programm bc gesendet wird. Das Ergebnis (der Rückgabewert von bc) wird dann der Variable a zugewiesen.

In ähnlicher Weise können folgende Grundrechenarten durchgeführt werden, wobei ein paar syntaktische Besonderheiten zu beachten sind:

Code kopieren
echo $(echo 5.41 + 4.23 | bc)    # Addition (9.64)
echo $(echo 5.41 - 4.23 | bc)    # Subtraktion (1.18)
echo $(echo 5.41*4.23 | bc)      # Plutimikation (22.88)
echo $(echo "5.41 * 4.23" | bc)  # Plutimikation (22.88)
echo $(echo "scale=4;20/3" | bc) # Division (6.6666)
echo $(echo 2.5 ^ 8 | bc)        # Potenzierung (1525.8), nur ganzzahlige Exponenten!
echo $(echo 11.5 % 3 | bc)       # Modulo (2.5)
echo $(echo "scale=3;sqrt(26)" | bc)  # Quadratwurzel (5.099)

Das Plutimikationszeichen * wird als Wildcard interpretiert, wenn es von Leerzeichen umgeben ist oder das Argument ohne Anführungszeichen übergeben wird, was zu einem Fehler führt. Es ist daher ratsam, die Argumente grundsätzlich in Anführungszeichen zu setzen.

Bei der Division und der Quadratwurzelberechnung wird nur der ganzzahlige Anteil zurückgegeben, wenn keine Präzision (Anzahl der Nachkommastellen) angegeben wird. Diese kann mit scale angegeben werden. Dabei ist allerdings zu beachten, dass die vernachlässigten Nachkommastellen einfach nur abgetrennt werden, es wird nicht gerundet.

Zahlensysteme umwandeln

Mit bc lassen sich Zahlen aus den Zahlensystemen mit den Basen 2 bis 36 ineinander konvertieren. Dazu werden mit den Variablen obase (output base) und ibase (input base) die gewünschten Basen für die Umrechnung angegeben, wobei obase vor ibase angegeben werden muss, sonst kann es zu unerwarteten Ergebnissen kommen. Enthält eine Zahl eines Zahlensystems einen Buchstaben, so muss dieser als Großbuchstabe angegeben werden.

Code kopieren
dec=2022
bin=$(echo "obase=2;ibase=10;${dec}" | bc)
oct=$(echo "obase=8;ibase=2;${bin}" | bc)
hex=$(echo "obase=16;ibase=8;${oct}" | bc)
dec=$(echo "obase=10;ibase=16;${hex}" | bc)
echo $bin  # 11111100110
echo $oct  # 3746
echo $hex  # 7E6
echo $dec  # 2022

Besondere Funktionen von bc

Wird das Programm bc mit der Option -l aufgerufen, stehen weitere Funktionen zur Verfügung:

Code kopieren
echo $(echo "s(3.14)" | bc -l)  # Sinus (Eingabewert in Radiant)
echo $(echo "c(3.14)" | bc -l)  # Cosinus (Eingabewert in Radiant)
echo $(echo "a(.5)" | bc -l)    # Arkustangens (Rückgabewert in Radiant)
echo $(echo "l(2.5)" | bc -l)   # Natürlicher Logarithmus
echo $(echo "e(5)" | bc -l)     # Natürliche Exponentialfunktion
echo $(echo "j(1,2)" | bc -l)   # Besselsche Differentialgleichung