Zahlensysteme

Programmierung

In der IT-Entwicklung gibt es einige Bereiche, in denen man regelmäßig mit verschiedenen Zahlensystemen zu tun hat. Codierung von Zahlen im Quelltext, Umwandlungen beim Lesen und Schreiben binärer Daten (z.B. Dateien), Umwandlung von Zahlen in Zeichenketten für die Ausgabe.
Zahlensysteme Darstellung von Zahlenwerten mit Zeichen
Java & Javascript parseInt, parseFloat, toString
Perl pack, unpack, printf, sprintf
PHP pack, unpack, printf, sprintf, base_convert, decbin, dechex, ...
SQL bin, oct, hex, cast
VBA&H, Oct, Hex, Val

Zahlensysteme in Java & Javascript

Quelltext:

Zahlen mit führender Ziffer '0' werden als Octalzahl (Basis 8) interpretiert.
Zahlen mit führender Dezimalziffer > '0' werden als Dezimalzahl (Basis 10) interpretiert.
Zahlen mit den führenden Zeichen '0x' werden als Hexadezimalzahl (Basis 16) interpretiert.
Binärzahlen lassen sich mit Hilfe der Funktion parseInt (s.u.) angeben.
Beispiele für die Codierung der Dezimalzahl 20:
x = 024; // octal
x = 20; // dezimal
x = 0x14; // hexadezimal
x = parseInt('10100',2); // binär
Codierung (Zahl String):
Die Methode toString() wird auf Zahlen-Objekte angewendet. Das Zahlensystem wird als Argument angegeben. Ohne Argument wird das Dezimalsystem angenommen.
So kann man auch Zahlen-Strings exotischer Zahlensysteme wie 7 oder 13 herstellen.
Die Methode funktioniert auch mit Gleitkomma-Zahlen und erzeugt in diesen Fällen einen KommaPunkt.
Beispiele:
s = x.toString(2); // binär
s = x.toString(8); // octal
s = x.toString(10); // dezimal
s = x.toString(); // dezimal
s = x.toString(16); // hexadezimal
Decodierung (String Zahl):
Die Funktion parseInt() versucht, einen String (erstes Argument) in eine ganze Zahl des Zahlensystems (zweites Argument) umzusetzen. Dabei wird der String von links nach rechts so lange abgearbeitet (parsing), bis ein unzulässiges Zeichen oder das String-Ende auftritt.
Wenn der String bereits mit einer unzulässigen Ziffer beginnt, gibt die Funktion den Wert NaN (Not a Number) zurück.
Wenn kein Zahlensystem angegeben ist, wird der String wie ein Quellcode (s.o.) interpretiert. Das kann bei Strings mit führenden Nullen (z.B. in Datum- oder Uhrzeit-Strings) dazu führen, dass diese irrtümlich als Octal-Zahlen interpretiert werden. Geben sie daher im Zweifel immer das Zahlensystem (10) an !
Die Funktion nimmt Hexadezimal-Zahlen an, wenn diese mit dem String '0x' beginnen.
Beispiele: (Dezimal-Ergebnis nach den Zeichen // )
s = "012.34";
x = parseInt(s); // 10.
x = parseInt(s,2); // 1.
x = parseInt(s,8); // 10.
x = parseInt(s,10); // 12.
x = parseInt(s,16); // 18.
x = parseInt("0x12"); // 18.
Die Funktion parseFloat() versucht, einen String in eine Gleitkomma-Dezimalzahl umzusetzen. Als Komma-Zeichen wird nur der Kommapunkt anerkannt.
Falls sie diese Funktion z.B. zur Decodierung von Eingabe-Daten verwenden, sollten sie allfällig enthaltene Komma-Beistriche (mit einem → Regulären Ausdruck) in Punkte umwandeln.
Beispiel: Eingabe mit Komma-Beistrich oder -Punkt
s = "012,34";
s = s.replace(/,/,".");   // Dezimalpunkt
x = parseFloat(s); // 12.34
Wenn die Decodierung von Zahlen-Strings nicht gelingt, dann liefern die beiden Funktionen parseInt() und parserFloat() keinen Fehler sondern den Wert NaN (Not a Number).
Einen Test auf NaN kann man nicht mit Vergleichs-Operatoren sondern nur mit der Funktion isNaN() durchführen !
Beispiel: Reaktion auf Eingabe-Fehler
s = "veler";
x = parseInt(s);
if(isNaN(x)) {...} // geeignete Maßnahmen
Live-Javascript Live-Javascript:
EingabeFunktionenDecodierungCodierung
  x1 = parseInt();
x2 = x1.toString();
 
 
leer 2 8 10 16
    Zahlensystem
x1 = parseFloat();
x2 = x1.toString();
 
 
Geben sie einen Ziffern-String (Text) in das Feld 'Eingabe' ein. Beim Verlassen des Feldes mit der Maus (onmouseout) sowie beim Anklicken (onclick) einer Zahlensystem-Option wird die Berechnung ausgeführt. Wenn ihr String Komma-Beistriche enthält, dann werden diese in Punkte umgewandelt. Mit den Funktionen parseInt() und parseFloat() wird versucht, daraus eine Zahl (Decodierung) zu ermitteln. Diese Zahl wird zuletzt mit Methode toString() wieder in einen Text verwandelt und angezeigt (Codierung).

Zahlensysteme in Perl

Quelltext:

Zahlen mit führender Ziffer '0' werden als Octalzahl (Basis 8) interpretiert.
Zahlen mit führender Dezimalziffer > '0' werden als Dezimalzahl (Basis 10) interpretiert.
Zahlen mit führenden Zeichen '0x' werden als Hexadezimalzahl (Basis 16) interpretiert.
Zahlen mit führenden Zeichen '0b' werden als Binärzahl (Basis 2) interpretiert.
In Strings kann man Zeichen auch mit ihrer → Code-Zahl eingeben. Zahlen nach \ werden octal interpretiert, Zahlen nach \x hexadezimal.
Dezimale Codes einzelner Zeichen kann man mit Funktion chr() oder pack() verwenden, z.B. zur Codierung von Bytes beliebiger Werte in einem String.
Mit pack() ist auch die Verwendung von Binärzahlen möglich. Die Bits werden einzeln als String aus "0" und "1" angegeben. Fehlende Bits werden rechts mit 0-Bits ergänzt.
Beispiele:
$x=011;   # 9.
$x=11;    # 11.
$x=0b11;  # 3.
$x=0x11; # 17.

$s="ABC";    # 'ABC'
$s="\101BC";  # 'ABC'
$s="\x41BC"; # 'ABC'
$s=chr(65)."BC"; # 'ABC'
$s=pack("c*",65,66,67); # 'ABC'
$s=pack("H*","414243"); # 'ABC'

$b=pack("B*","10000001"); # Byte 0x81

Codierung:

Die Funktionen pack() und unpack() führen alle anfallenden Umwandlungs-Aufgaben durch. Diese Funktionen sind so erfolgreich, dass sie auch in andere Programmiersprachen übersiedelt wurden.
pack() wird eingesetzt, um Zahlen binär zu codieren, um sie z.B. in Binär-Dateien zu schreiben.
Das Beispiel rechts zeigt die Binär-Codierung der Dezimalzahl 123 mit verschiedenen Optionen von pack(). In der Folge-Zeile jeweils die erzeugten Daten-Bytes in Hex-Darstellung.
Beachten sie, dass die Bytes normalerweise in umgekehrter Reihenfolge gespeichert werden, d.h. das niedrigst-wertige Byte zuerst, das höchstwertige Byte zuletzt.
Details zur Verwendung der Funktionen pack() und unpack()
Details zur Codierung von Gleitkomma-Zahlen nach IEEE-754
Beispiele:
$n=123;
$s2=pack("S",$n); # Ganze Zahl 'short' ->
# 2 Bytes: 7B 00

$s4=pack("L",$n); # Ganze Zahl 'long' ->
# 4 Bytes: 7B 00 00 00

$s4=pack("f",$n); # Gleitkomma 'single' ->
# 4 Bytes: 00 00 F6 42

$s8=pack("d",$n); # Gleitkomma 'double' ->
# 8 Bytes: 00 00 00 00 00 C0 5E 40

Decodierung:

unpack() wird z.B. eingesetzt, um Binär-Dateien zu lesen und gelesene Bytes (Bitmuster) in verwendbare Daten (z.B. Zahlen) zu decodieren.
Das Beispiel rechts zeigt die Decodierung eines Binär-Strings mit verschiedenen Optionen von unpack().
Die Bytes des Strings werden hier zuerst als Quelltext (mit Octalzahlen) eingegeben. Alternativ kann man dazu die Funktion pack() verwenden
Die Funktion entnimmt aus dem String nur so viele Bytes wie benötigt, d.h. "S" (short) erzeugt eine ganze Dezimalzahl aus den ersten beiden Bytes, "L" eine ganze Dezimalzahl aus den ersten 4 Bytes, "f" eine Gleitkommazahl aus 4 Bytes, und "d" eine Gleitkommazahl aus allen 8 Bytes.
Das Template "H*" eignet sich gut zur Erzeugung lesbarer Hex-Strings (dump) aus beliebig langen Binärdaten-Strings.
Bei der Decodierung wird die übliche Byte-Reihenfolge angenommen, d.h. das niedrigst-wertige Byte zuerst. pack und unpack bieten jedoch auch Optionen für die umgekehrte Byte-Reihenfolge.
Details zur Verwendung der Funktionen pack und unpack
Details zur Codierung von Gleitkomma-Zahlen nach IEEE-754.
Beispiele:
$s="\1\2\3\4\5\6\7\10";
$s=pack("c8",1,2,3,4,5,6,7,8);
# 8 Bytes: 01 02 03 04 05 06 07 08
$n=unpack("S",$s);
# 513.
$n=unpack("L",$s);
# 67305985.
$n=unpack("f",$s);
# 1.5399896E-36
$n=unpack("d",$s);
# 5.44760372201161E-270
$t=unpack("H*",$s.chr(16).chr(255));
# 00010203040506070810FF
Vorsicht !
Einige Optionen der Funktionen pack() und unpack() sind von der Umgebung (Betriebssystem) abhängig. Je nach System kann z.B. die Länge der Variablen oder die Reihenfolge der Bytes varieren.

Testen sie daher nach Möglichkeit ihre Programme bzw. die codierten / decodierten Daten auf allen erreichbaren Systemen !

Formatierung eines Zahlen-Strings:

Die Funktion printf() führt die Ausgabe formatierter Strings aus und bietet dafür zahlreiche Optionen.
Funktion sprintf() liefert den formatierten String für weitere Verarbeitung.
Rechts einige Beispiele mit den Optionen "%d" für Ganze Zahlen, "%f" für Gleitkomma-Zahlen und "%X" für Hexadezimal-Zahlen.
Eine Zahl nach dem "%" legt die Anzahl der Ausgabe-Zeichen fest, ein zusätzlich vorangestelltes Zeichen "0" oder " " füllt damit bis zur gewünschten Länge. Alle anderen Zeichen im Format-String werden direkt wiedergegeben.
printf() mit Option '%X' wird nur für die Ausgabe einzelner Hex-Zahlen verwendet.
Spezialfälle:
Zur Hex-Ausgabe von Strings kann man die Funktion unpack() (s.o.) verwenden.
Die gleiche Funktion eignet sich auch zur Ausgabe von Binär-Codes, hier angewendet auf ein einzelnes Byte mit dem Dezimalwert 10.
Details dazu in der ausführlichen Perl-Referenz unter perlfunc .
Beispiele:
$i=123.456;
printf("%d",$i); # 123
$s=sprintf("%d",$i);
print "i=$s"; # i=123
printf("%05d",$i); # 00123
printf("%f",$i); # 123.456
printf("% 7.2f",$i); # 123.46
printf("%X",$i); # 7B
printf("0x%X",$i); # 0x7B
$s="ABC\n";
print uc(unpack("H*",$s));
# 4142430A
print unpack("B*","\x0A");
# 00001010

Dezimal ↔ Hex String

Das Beispiel rechts zeigt eine der Möglichkeiten für diese häufig gebrauchte Umwandlung.
Zum Test wird eine (dezimale) Zufallszahl erzeugt.
Die Standard-Funktion sprintf() wird zur Codierung eines Hex-Strings verwendet (hier mit 4 Ziffern).
Im zweiten Teil wird der Hex String mit einem vorangestellten 0x in eine für Perl verwendbare Form gebracht. Der Hex String wird mit hex() oder eval() interpretiert (hex() kann auch auf das Prefix 0x verzichten).
Wenn negative Werte im → 2er-Komplement codiert sind, dann müssen sie nach der Umwandlung in eine Dezimalzahl umgeformt werden. Dazu wird das höchstwertige Bit (Hex-Ziffer 0x8) getestet. Das Beispiel rechts ergibt
dezimal(0xFFFFFF80)=-128

Dezimalzahl → Hex String
my $x = int(rand(100));
my $y = sprintf("%04X",$x);
print "hex($x)=$y\n";
Hex String → Dezimalzahl
my $z = "0x".$y;
my $r = hex($z);
# eval("\$r=$z;");
print "dezimal($z)=$r\n";
Negative Werte im 2er-Komplement:
$z = "0xFFFFFF80";
$r = hex($z);
if($r & 0x80000000) {$r=$r-0xFFFFFFFF-1;}
print "dezimal($z)=$r\n";
Typ-Umwandlung
Perl kennt keine "Typbindung", d.h. die Daten werden intern jeweils in jenen Typ (String, Ganze Zahl, Gleitkomma-Zahl) umgewandelt, der im gegebenen Zusammenhang 'richtig' erscheint. In manchen Fällen ist es notwendig, einen bestimmten Typ zu erzwingen: Benutzen sie in diesem Fall Operatoren oder Funktionen.
$a="12345";
// Ganze Zahl (integer)
$b=$a+0;
// Gleitkomma-Zahl (double)
$c=$b+0.0;
// String
$d=$c."";

Zahlensysteme in PHP

Quelltext:

Zahlen mit führender Ziffer '0' werden als Octalzahl (Basis 8) interpretiert.
Zahlen mit führender Dezimalziffer > '0' werden als Dezimalzahl (Basis 10) interpretiert.
Zahlen mit führenden Zeichen '0x' werden als Hexadezimalzahl (Basis 16) interpretiert.

Im Zweifel addiert man die Zahl 0 zu einer Variablen: Sie wird dann immer als Zahl interpretiert:
$zal = $_GET['xyz']+0;

Codierung und Decodierung:

Die Funktion pack() führt nach ↑ Perl-Muster alle anfallenden Umwandlungs-Aufgaben durch.
Je nach Version sind evtl. manche Optionen nicht verfügbar.
Funktion unpack() arbeitet auf PHP etwas anders als in Perl und liefert ein → Array.

Details dazu in der offiziellen PHP-Referenz (de): pack, unpack.
Codierung einer ganzen Zahl in Binär-Code:
$s = pack('L',123456);
Die Variable $s enthält danach 4 Byte: 40 E2 01 00

Decodierung von Binär-Code mit der oben erzeugten 4-Byte-Variablen $s
$na = unpack("L",$s);
Das Array $na enthält danach 1 Element mit dem Wert = 12345

Formatierung eines Zahlen-Strings:

Die Funktionen printf() und sprintf() funktionieren nach ↑ Perl-Muster.
Details zur Funktion sprintf
Beispiel: Ausgabe als Hexadezimal-Zahl:
print sprintf('#%04X',171);
ergibt #00AB

Umwandlungs-Funktionen

PHP bietet einige Funktionen zur Umwandlung von/in verschiedene Zahlensysteme.

base_convert (numstring, from, to)
übersetzt Zahlen-Strings beliebiger Zahlensysteme, z.B.
$binstr = base_convert('A1', 16, 2);
übersetzt die dezimale Zahl 161.0 von Hexadezimal (16) nach Binär (2) und ergibt
$binstr = '10100001';
Diese Funktion kann auch exotische Zahlensysteme übersetzen, z.B. mit Basis 3, 4, 5,, ...36

intval (numstring, from)
übersetzt Strings zu ganzen dezimalen Zahlenwerten, z.B.
$decnum = intval('A1', 16);
übersetzt einen hexadezimalen Zahlen-String in dem Wert
$decnum = 161;
Vorsicht: Gleitkomma-Werte werden abgeschnitten, das Verhalten beim Überschreiten der Typ-Grenzen (overflow, underflow) kann je nach Betriebssystem variieren.

Diese Funktionen dienen zur Umwandlung von Zahlen-Strings verschiedener Systeme. Dezimale Werte können auch als Zahlenwerte (Ohne "") angegeben werden:
bindec, decbin, dechex, decoct, hexdec, octdec
Beispiele:
decbin(12) = '1100'
decoct(12) = '14'
dechex(12) = 'c'
bindec('1101') = 13
octdec('15') = 13
hexdec('D') = 13

Details in der offiziellen PHP-Referenz (de): base_convert, bindec, decbin, hexdec, dechex, octdec, decoct

Zahlensysteme in SQL

SQL ist zwar ein Standard, daneben existieren jedoch zahlreiche SQL-Dialekte, abhängig von Datenbank-Hersteller und Version. Auch vom SQL-Standard gibt es mehrere Versionen. Die Angaben müssen daher sehr vorsichtig interpretiert und mit der eigenen Datenbank getestet werden.
Als Richtwert gelten die Angaben für MySQL Version 6

Dezimalzahlen

Gleitkomma-Zahlen werden immer mit Komma-Punkt angegeben.
Besonders kleine oder große Werte werden in Exponential-Schreibweise angegeben.

Beispiel:
SELECT 123.456, 6.023e+23;

Hexadezimale Zahlen

werden wie in ODBC mit führendem 0x und einer geraden (!) Anzahl hexadezimaler Stellen angegeben. Ohne weitere Angaben werden hexadezimale Werte immer als Strings (!) interpretiert.
Addition einer Zahl (Beispiel rechts) erzwingt die Verwendung als Zahl.
Die Funktion CAST() garantiert die Verwendung der angegebenen Type

Beispiel: Formulierung der Zahl 246.0 dezimal:
SELECT 0xF6+0;
SELECT CAST(0xF6 AS UNSIGNED);

Hexadezimale Strings (Zeichenketten)

werden in dieser Form angegeben: x'HH' oder X'hhhh'
Sowohl das führende X als auch die hexadezimalen Ziffern können als Groß- oder Kleinbuchstaben verwendet werden. Es ist nur eine gerade Anzahl hexadezimaler Ziffern erlaubt. Je 2 Hex-Ziffern werden als Zeichen interpretiert.

Beispiel: Formulierung des Strings SQL als Hex-String:
SELECT x'53514C';

Details Details zum Thema Zeichen-Code

Ausgabe hexadezimaler Strings

Zur Ausgabe wird die Funktion HEX() verwendet.
Beispiel:
SELECT HEX('SQL');
ergibt 53514C

Binäre Zahlen

werden mit führendem b'BB' oder 0b'BB' angegeben. Ohne weitere Angaben werden die Daten als Strings interpretiert.
Addition von 0 oder die Funktion CAST() erzwingen die Verwendung als Zahl.

Zur Ausgabe wird die Funktion BIN() verwendet.
Beispiel: Formulierung der Zahl 12 dezimal:
SELECT 0b'01100'+0;
SELECT CAST(b'1100' AS UNSIGNED);
Ausgabe:
SELECT 12,BIN(12);
ergibt 12  1100

Octale Zahlen

Zur Ausgabe wird die Funktion OCT() verwendet.

Ausgabe:
SELECT 12,OCT(12);
ergibt 12 14

Zahlensysteme in VBA

Quelltext:

Zahlen ohne weitere Angaben werden als Dezimalzahl (Basis 10) interpretiert, auch solche mit führenden Nullen.
Zahlen mit führenden Zeichen '&H' werden als Hexadezimalzahlen (Basis 16) interpretiert.
Beispiele:
x = 11   ' 11.
x = &H11 ' 17.

Codierung von Zahlen-Strings:

Funktion Hex() wandelt eine Zahl in einen Hexadezimal-String um.
Funktion Oct() wandelt eine Zahl in einen Octal-String um.
s = Hex(123)
' 7B
s = Oct(123)
' 173
Die Standard-Funktion Val() kann man zur Decodierung von Hex-Strings verwenden.
dec = Val("&H" & hexstring)
Muster einer Funktion dec_to_bin() zur Umwandlung einer positiven ganzen Zahl in einen Binär-String (Codierung, ohne Gewähr).

Für den Zahlenwert decnumber=0 wird der Algorithmus umgangen und der String bin=0 eingesetzt.

Zuerst wird die größte benötigte Binärstelle istart ermittelt. Dann werden - beginnend mit istart - die binären Ziffern in einer Schleife durchlaufen, von der höchstwertigen zur niedrigst-wertigen.
Variable j ist der Stellenwert, Variable b die Binärziffer.

Damit ist die einfache Berechnung abgeschlossen.

Optional (Quelltext in grün) kann man den erzeugten String in eine bestimmte Länge umwandeln. Die Anzahl Binärstellen wird mit digits optional vorgegeben.
Wenn digits nicht angegeben wird, dann wird der Binärstring so zurückgegeben wie berechnet.
Wenn digits > Anzahl der berechneten Binärstellen, dann wird der String mit führenden Nullen ergänzt.
Wenn digits < Anzahl der berechneten Binärstellen, dann wird ein Fehlerwert (hier Fehler Nr. 1000) zurückgegeben.
Function dec_to_bin(decnumber As Double optional digits as Integer=0) As String
Dim i, j, b, istart As Integer
Dim d As Long
Dim bin As String
d = CLng(decnumber)
If (d = 0) Then
bin = "0"
Else
istart = Int(Log(d) / Log(2))
For i = istart To 0 Step -1
j = 2 ^ i
b = d \ j
If b > 0 Then
bin = bin & "1"
Else
bin = bin & "0"
End If
d = d - b * j
Next
End If
If digits > 0 Then
If Len(bin) > digits Then
Err.Raise 1000
Else
bin = String(digits,"0") & bin
bin = Right(bin, digits)
End If
End If
dec_to_bin = bin
End Function
Muster einer Funktion bin_to_dec() zur Umwandlung eines Binärstrings (Binärzahl als Zeichenkette) in eine Dezimalzahl (Decodierung, ohne Gewähr).

In der Schleife wird je eine Ziffer bd aus dem String entnommen und in eine Zahl n umgewandelt. Die Dezimalzahl dec wird schrittweise aufgebaut, indem ihr jeweiliger Wert mit 2 multipliziert und die Binärziffer addiert wird.

Jedes andere Zeichen als "0" oder "1" bewirkt die Rückgabe eines Fehlerwerts (hier Fehler Nr. 1000)
Function bin_to_dec(binstring As String) As Long
Dim i, n As Integer
Dim dec As Long
Dim bd, s As String
s = binstring
dec = 0
For i = 1 To Len(s)
bd = Mid(s, i, 1)
If (bd = "0" Or bd = "1") Then
n = Val(bd)
Else
Err.Raise 1000
End If
dec = 2 * dec + n
Next
bin_to_dec = dec
End Function

XHTML CSS