Was ist was? · bei.pm

In dieser Rubrik gibt es Artikel über Dateiformate und Reverse Engineering.

Nun ist es aber so:
Es gibt da draußen viele Programmiersprachen und viele Leute, die manche Dinge unter völlig anderen Namen kennen - oder gar keine Ahnung von der Existenz fundamentalster Dinge haben, weil ihre Programmiersprache das von ihnen wegabstrahiert.

tl;dr:
Meine Notation orientiert sich grob an C99 <stdint.h>. Wer mit dieser Notation etwas anfangen kann, wird mit meiner Notation sicher klarkommen.

Integer

Integer sind schlicht gesagt Ganz-Zahlen, sprich Zahlen ohne Nachkomma-Anteil.

Dabei sind Integer in Datenformaten in aller Regel innerhalb eines festen Zahlenspektrums, quasi einer Auflösung, definiert. Diese gebe ich dabei in Bit an - aus dem Grunde, da ein "Byte" und darauf aufbauende Typen (Word, Qword, ...) in aller Regel Plattformabhängig sind.

Zudem unterscheidet man bei Integer-Typen auch noch zwischen natürlichen Zahlen (ℕ, sprich, ohne Vorzeichen - Unsigned) und ganzen Zahlen (ℤ, sprich, mit Vorzeichen - Signed).
Diese Information ist über ein Vorzeichen im Bezeichner (u oder s) ersichtlich.

Dabei ist es möglich, dass vorzeichenbehaftete Ganzzahlen entweder als Einerkomplement dargestellt werden oder als Zweierkomplement.
Solange es nicht anders angegeben ist, wird das Zweierkomplement verwendet, da es in der modernen Informatik die bevorzugte Darstellung bildet.

Vorzeichenlose Zahlen werden von mir in meinen Dokumentationen als uint angegeben, mit darauffolgender Angabe der Genauigkeit in Bits.
Vorzeichenbehaftete Zahlen werden von mir in meinen Dokumentationen als sint angegeben, ebenso mit darauffolgender Angabe der Genauigkeit in Bits.

Ich verzichte auf die Verwendung des Datentyps "char" für Zeichen, da Zeichenketten in der Regel nur Integer-Werte-Ketten mit einer speziellen Intepretation darstellen.
Diese werden daher als uint(8)[] dargestellt.

Beispiele:

Notation C99 stdint.h-Äquivalent Beschreibung Zahlenraum
uint(16) uint16_t Unsigned Integer, 16 Bit Länge 0 - 65.535
sint(8) int8_t Signed Integer, 8 Bit Länge, Zweierkomplement -126 - 127
uint(24) uint32_t:24 Unsigned Integer, 24 Bit Länge 0 - 16.777.216

Festkomma-Werte

Festkomma-Werte sind Zahlenwerte aus dem Spektrum der Rationalen Zahlen (Q), die somit über ein Komma sowie Nachkomma-Stellen verfügen.

Bei Festkomma-Werten ist - daher auch der Name - die Position des Kommas durch den Datentyp fest vorgegeben.
Dadurch ergibt sich auch ein fester Zahlenbereich für Zahlen dieses Datentyps; mathematisch ausgedrückt ist der Zahlenraum endlich.

In der Realität wird dieser Datentyp vorwiegend bei Plattformen ohne hinreichend schnelle Fließkomma-Hardware-Einheit eingesetzt, da die Berechnung von Festkomma-Werten durch Integer-Einheiten erfolgen kann.

Auch wird der Datentyp zum Beispiel von Datenbank-Management-Systemen verwendet, wenn feste Anforderungen erfüllt werden müssen.
Man denke hier beispielsweise an Systeme zur dauerhaften Speicherung von Finanzdaten; die meisten Währungen beschränken sich auf 2 Stellen nach dem Komma. (Es ist aber nicht klug, hierfür Festkomma-Werte zu nehmen; schlauer ist es, stattdessen direkt die kleinste Währungs-Einheit als Integer zu speichern und den Rest der Darstellungs-Ebene zu überlassen)

Analog zu den Integer-Angaben gebe ich bei Festkomma-Werten die Auflösung der Zahl vor und nach dem Komma an:
ufixed(9,7) bezeichnet einen Datentyp, der vorzeichenlos 9 Bit für den Wert vor dem Komma, sowie 7 Bit für den Wert nach dem Komma reserviert; in Summe also 16 Bit breit ist und so beispielsweise als Vektor zweier voneinander unabhängiger Integer einen Bereich von (0,0) bis (511,127) abdecken kann.
Diese Interpretation würde allerdings in ihrer Dezimaldarstellung 28 Zahlen ungenutzt verschenken, da man sich wahrscheinlich eher auf maximal (511,99) in der Praxis beschränken würde.

Anstatt einer direkten Interpretation des Festkomma-Wertes als einen Vektor aus 2 separaten Integern - was quasi immer einen ungenutzten Datenbereich bei der Umwandlung in Dezimalzahlen und einen manuellen Übertrag bedeutet - kann stattdessen auch der Nachkomma-Bereich als Bruch ihrer gesamten Auflösung interpretiert werden.
Am Beispiel des soeben genannten ufixed(9,7) ergibt sich somit ein Bruch über einen Nenner in Höhe von 27 - der Zahlenbereich geht dann von 0,00 bis 511 + 126127 Zur Umwandlung in eine Dezimaldarstellung wäre die Nachkomma-Stelle daher durch 128 zu teilen.
Mit dieser Variante lassen sich einfacher Rechen-Operationen durchführen, da der Übertrag sich automatisch ergibt, wodurch diese Variante in aller Regel bevorzugt wird.
Diese Variante hat allerdings den Nachteil, dass die Nachkommastellen in der Dezimaldarstellung nicht mehr über eine garantierte Auflösung verfügen, eine einzelne Dezimalstelle also nicht mehr den Gegenwert 0.01, sondern 0.007874 besitzt, was zu entsprechenden Rundungsfehlern führen wird.

Welche Interpretationsweise verwendet wird, wird entsprechend an der Verwendungsstelle dokumentiert.

Fließkomma- bzw. Gleitkomma-Werte

Fließkomma-Werte sind mathematisch komplexere Ausdrücke, bei denen eine Ganzzahl mit fester Auflösung über einen mathematischen Term so ausgedrückt wird, dass effektiv der Nachkomma-Teil durch Verschiebung gebildet wird - und sich damit unmittelbar an der wissenschaftlichen Notation orientiert.
Die gebräuchlichste Weise, dies umzusetzen, wurde mit IEEE 754 standardisiert und ist seitdem international anerkannt.

Dabei besteht ein Fließkomma-Wert in der Regel aus den folgenden Komponenten:

Vorzeichen (0 oder 1) Exponent Mantisse

Während das Vorzeichen als binäre Ja/Nein-Information einfach erschlossen werden kann, bildet sich die eigentliche Zahl über die Gleichung
Mantisse * 2Exponent

Zusätzlich gibt es noch eine Reihe konstanter Werte, die besondere Fälle rationaler Zahlen abdeckt - darunter ±∞ und NaN ("keine gültige Zahl").

Fließkomma-Werte sind vor allem dann nützlich, wenn die Genauigkeit nicht so wichtig ist, da es bei dieser Art von Werten zwangsläufig zu Rundungsfehlern und somit Genauigkeitsverlusten kommt. Typischerweise werden Fließkomma-Werte daher zum Beispiel zur Definition von Koordinaten, wie Vertex-Vektoren in 3D-Modellen oder Bézier-/Spline-Kurven für optische Repräsentations-Zwecken verwendet.

In den Datenformaten werden Fließkomma-Werte als float(Mantisse, Exponent) spezifiziert.
Wird ein von IEEE 754 abweichendes Format verwendet, so wird dies entsprechend angegeben.