Login
Newsletter
Werbung

Do, 16. März 2017, 15:00

Shellskripte mit Aha-Effekt: Zahlenspiele

Zahlenumwandlung mit printf

Was aber, wenn kein bc zur Verfügung steht, weil er auf dem Kundenserver nicht installiert wurde? Nachinstallation auf einem fremden System geht ja nun mal nicht. Wenn eine bash verfügbar ist, hilft bei der Umwandlung von Dezimalwerten in Hex-Zahlen die Funktion printf. Diese Zeilen definieren die Umwandlung als Shell-Funktion. Der Aufruf X=$(Hex 123) ; echo $X liefert dann wunschgemäß den Wert 7B:

01 Hex() # (Val)
02   {
03   VAL=$1
04   printf "%0X" $VAL
05   }

Bei der Umwandlung von Dezimalzahlen in Binärwerte ist es nicht ganz so einfach. Hier gilt es, wirklich zu programmieren. Es kommt das Horner-Schema für die Zahlenumwandlung zum Einsatz, das prinzipiell die Konvertierung beliebiger Zahlensysteme erlaubt. Das Horner-Schema dient vor allem zum Berechnen von Polynomen. Hier tritt die Zahlenbasis an die Stelle der Unbekannten, und die ermittelten Ziffern sind Koeffizienten des Polynoms. Klar wird das bei der Polynomschreibweise einer Zahl, etwa 3514 = 3*103 + 5*102 + 1*101 + 4.

Um beispielsweise die Dezimalzahl 123 ins Binärsystem umzuwandeln, hilft folgendes Schema:

  • Die Zahl wird durch 2 geteilt mit Rest.
  • Der Divisionsrest wird notiert.
  • Ist der ganzzahlige Quotient = 0, ist man fertig, andernfalls nimmt man ihn als neue Zahl und wiederholt den Durchlauf.

Das heißt also:

123 : 2 = 61 Rest: 1
61 : 2 = 30 Rest: 1
30 : 2 = 15 Rest: 0
15 : 2 = 7 Rest: 1
7 : 2 = 3 Rest: 1
3 : 2 = 1 Rest: 1
3 : 2 = 1 Rest: 1
1 : 2 = 0 Rest: 1

Um die endgültige Binärzahl zu erhalten, schreibt man die Divisionsreste beginnend von letzen Wert (unten) bis zum ersten Wert (oben) nieder. Die Berechnung liefert dann für das Beispiel 1111011.

Ein Shellskript realisiert das Aufschreiben von unten nach oben dadurch, dass der Programmierer den neu ermittelten Rest stets vor das bisherige Resultat schreibt. Außerdem ersetzt er die Division durch 2 mit einem Schiebebefehl und die Ermittlung des Rests durch das Abschneiden der letzten Stelle mittels UND-Verknüpfung. Beide Operationen sind meist schneller als die Division. Im Übrigen kommt der geschilderte Algorithmus eins zu eins zur Anwendung.

Das folgende Skript definiert wieder eine Shell-Funktion (Zeile 01). Zeilen 03 und 04 initialisieren Startwert und Resultat. Die Schleife (Zeilen 05 bis 08) läuft durch, bis der Quotient 0 geworden ist. Zeile 06 ermittelt den Divisionsrest durch eine UND-Verknüpfung mit 1 und setzt die letzte Stelle vor die Ergebnis-Variable. Zeile 07 dividiert den Wert VAL per Rechtsschieben durch 2. Das Echo-Kommando in Zeile 09 gibt nur den Wert zurück - ohne Zeilenvorschub.

01 Binary() # (VAL)
02   {
03   VAL=$1
04   RESULT=""
05   while [ $VAL -ne 0 ] ; do
06      RESULT=$(( $VAL & 1 ))$RESULT
07      VAL=$(( $VAL >> 1 ))
08   done
09   echo -n $RESULT
10   }

Ein Probelauf zeigt die gewünschten Ergebnisse:

$ X=$(Binary 123) ; echo $X
1111011
$ X=$(Binary 65) ; echo $X
1000001
$ X=$(Hex 123) ; echo $X
7B
$ X=$(Hex 65) ; echo $X
41

Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung