Fliesskommazahlen Flashcards
Typen 𝚏𝚕𝚘𝚊𝚝 und 𝚍𝚘𝚞𝚋𝚕𝚎; Gemischte Ausdrücke und Konversionen; Löcher im Wertebereich; Fliesskommasysteme; IEEE-Standart; Grenzen der Arithmetik; Richtlinien;
Wie unterscheiden sich Fliess- von Fixkommazahlen? Was sind die Vorteile von Fliesskommazahlen gegenüber den Fixkommazahlen?
Fixkommazahlen haben eine feste Anzahl vor- und Nachkommastellen. Der Wertebereich wird somit noch kleiner als bei ganzen Zahlen, da ab mehr als 10 Stellen alles hintendran weggekürzt wird. Die Repäsentierbarkeit hängt also von der Stelle des Kommas ab.
Bei Fliesskommazahlen hingegen bleibt die Anzahl signifikanter Stellen konstant, z.B. 0.0824 = 8.24 * 10⁻². Die verfügbaren Stellen werden also nicht für Nullen vergeudet und sind daher präziser.
Was sind die Typen 𝚏𝚕𝚘𝚊𝚝 und 𝚍𝚘𝚞𝚋𝚕𝚎? Wofür werden sie gebraucht?
Tipp: 4 Eigenschaften
- Fundamentale C++-Typen für Fliesskommazahlen.
- Approximieren den Körper der reellen Zahlen (ℝ, +, *).
- Haben grossen Wertebereich.
- Sind auf den meisten Rechnern sehr schnell.
Wie gross sind die Wertebereiche von 𝚏𝚕𝚘𝚊𝚝 und 𝚍𝚘𝚞𝚋𝚕𝚎?
𝚏𝚕𝚘𝚊𝚝: ca. 7 Stellen, Exponent bis ± 38
𝚍𝚘𝚞𝚋𝚕𝚎: ca. 15 Stellen, Exponent bis ± 308 .
Wie unterscheidet sich der Wertebereich von 𝚏𝚕𝚘𝚊𝚝 und 𝚍𝚘𝚞𝚋𝚕𝚎 gegenüber dem von 𝚒𝚗𝚝?
Was sind Vor- und Nachteile der beiden Typen?
Ganzzahlige Typen (𝚒𝚗𝚝):
- Über- und Unterlauf häufig, aber…
- Wertebereich ist zusammenhängend (keine Löcher): “ℤ ist diskret.”
Fliesskommatypen (𝚏𝚕𝚘𝚊𝚝, 𝚍𝚘𝚞𝚋𝚕𝚎):
- Über- und Unterlauf selten, aber…
- Es gibt Löcher: ℝ ist “kontinuierlich”.
Wie unterscheiden sich die arithmetischen Operatoren bei 𝚏𝚕𝚘𝚊𝚝 und 𝚍𝚘𝚞𝚋𝚕𝚎 von 𝚒𝚗𝚝?
Die meisten Operationen sind gleich wie bei 𝚒𝚗𝚝. Der Divisionsoperator jedoch modelliert “echte”, nicht ganzzahlige Division. Folglich existiert auch kein Modulo-Operator.
Wie würde man die Zahlen 1.234 und 0.0001234 für Typen 𝚏𝚕𝚘𝚊𝚝 und 𝚍𝚘𝚞𝚋𝚕𝚎 eingeben?
Geht sowohl mit Dezimalkomma als auch mit Exponent. Geeigneter wären jeweils: 𝟷.𝟸𝟹𝟺 bzw. 𝟷.𝟸𝟹𝟺𝚏 (float) sowie 𝟷.𝟸𝟹𝟺𝚎-𝟺 bzw. 𝟷.𝟸𝟹𝟺𝚎-𝟺𝚏 (float).
Wie ist ein Fliesskommasystem definiert?
Ein Fliesskommazahlensystem F ist durch vier natürliche Zahlen gegeben:
F (β, p, e(min), e(max)), wobei:
- β ≥ 2, die Basis.
- p ≥ 1, die Präzision (Stellenanzahl).
- e(min), der kleinste Exponent.
- e(max), der grösste Exponent.
Welche Zahlen enthält ein Fliesskommasystem F? Wie stellt man sie zu einer Basis β dar?
F: ± Σᵖ⁻¹ᵢ₌₀ (dᵢβ⁻ᶦ * βᵉ),
für dᵢ ∈ {0, …, β-1} und e ∈ {e(min), …, e(max)}.
In Basis-β-Darstellung:
± d₀ , d₁d₂…dₚ₋₁ * βᵉ
(Man kann sich die dᵢ als einzelne Stellen / Ziffern der ganzen Zahl vorstellen.)
Was ist die normalisierte Darstellung einer Zahl im binären Fliesskommasystem?
In der normalisierten Darstellung
± d₀ , d₁d₂…dₚ₋₁ * βᵉ für d₀ ≠ 0
wird immer eine Ziffer (in Binär also die 1) vor das Komma gesetzt und die Zahl dann mit dem passenden Exponenten multipliziert, z.B. für die Zahl 0.625 im Dezimalsystem würde man im Binärsystem nicht 0.𝟷0𝟷 schreiben sondern 𝟷.0𝟷𝚎-𝟷.
Die normalisierte Darstellung ist eindeutig und deshalb zu bevorzugen.
Wie rechnet man 1.1₁₀ ins Binärzahlensystem um?
Wir subtrahieren von 1.1 die ganzzahligen Einheiten, die in 1.1 enthalten sind (also 1), multiplizieren den Rest mit 2 und führen die Kette so fort: 1.1 - 1 = 0.1; 0.1 * 2 = 0.2; 0.2 - 0 = 0.2; 0.2 * 2 = 0.4; 0.4 - 0 = 0.4; 0.4 * 2 = 0.8; 0.8 - 0 = 0.8; 0.8 * 2 = 1.6; 1.6 - 1 = 0.6; 0.6 * 2 = 1.2; 1.2 - 1 = 0.2; 0.2 * 2 = 0.4; (ab hier wird die Kette periodisch). Nun setzen wir nach der ersten Zahl ein Komma und erhalten: 1.0¯0011 ("1.0 Periode 0011")
Weswegen erhält man vom Computer für die Subtraktion zweier Fliesskommazahlen 𝟷.𝟷𝚏 - 𝟷.0𝚏 nicht 0.𝟷, sondern eine “willkürliche” kleine Zahl?
Da 𝟷.𝟷𝚏 und 0.𝟷𝚏 nicht gleich 1.1 und 0.1 sind, sondern geringfügig fehlerhafte Approximationen dieser Zahlen. Dies folgt aus den periodischen bzw. nicht abbrechenden Eigenschaften einer ins Binärsystem konvertierten Zahl.
𝟷.𝟷 (double) wäre 1.1000000000000000888178… und 𝟷.𝟷𝚏 wäre 1.1000000238418… .
Berechne für ein Fliesskommasystem F(β = 2, p = 4) folgende Addition:
1.111 * 2⁻² + 1.011 * 2⁻¹
Was sind die Schritte?
Zuerst Exponenten anpassen für 2⁰:
- 111 * 2⁻² = 0.01111 * 2⁰
- 011 * 2⁻¹ = 0.1011 * 2⁰
Nun kann man diese beiden Werte addieren und erhält:
0.01111 + 0.1011 = 1.0001
Da p = 4, müssen wir die Zahl auf die nächste darstellbare Zahl mit p signifikanten Stellen runden, also 1.001, was das Ergebnis ist.
In welche drei Teile zerlegt sich eine Fliesskommazahl in der Computerdarstellung? Was für normalisierte Fliesskommasysteme F* folgen daraus für ein 32-Bit- und ein 64-Bit-System?
Vorzeichen, Exponent und Mantisse (den Signifikanden).
Bei 32-Bit: 1 Bit Vorzeichen, 8 Bits Exponent, 23 Bit Mantisse. Daraus folgt: F(2, 24, -126, 127).
Bei 64-Bit: 1 Bit Vorzeichen, 11 Bits Exponent, 52 Bit Mantisse. Daraus folgt: F(2, 53, -1022, 1023).
Betrachte folgenden Programmausschnitt:
𝚏𝚘𝚛 (𝚏𝚕𝚘𝚊𝚝 𝚒 = 0.𝟷; 𝚒 != 𝟷.0; 𝚒 += 0.𝟷)
𝚜𝚝𝚍::𝚌𝚘𝚞𝚝 «_space;𝚒 «_space;“\𝚗”;
Wo liegt hier das Problem?
Da i niemals exakt 1 ist, wird dies eine Endlosschleife werden.
Betrachte die Addition: 1.000 * 2⁵ + 1.000 * 2⁰. Wo liegt das Problem? Was wird das Ergebnis sein?
1.000 * 2⁵ + 1.000 * 2⁰ = 1.00001 * 2⁵.
Da jedoch p = 4 für die ersten beiden Zahlen, wird auch das Ergebnis auf 4 Stellen gerundet, und man erhält: 1.000 * 2⁵. Die Addition hat also keinen Effekt.