Nicht jede Dezimal-Zahl ist binär exakt codierbar. Bereits hier könnte es ohne eindeutige Typangaben zu internen Rundungsfehlern kommen. Beispiel:
Delphi-Quellcode:
CONST
CompilerVersion_e: Extended = 34.1;
CompilerVersion_s: Single = 34.1;
CompilerVersion_d: Double = 34.1;
CompilerVersion_o = 34.1; // o: Ohne Typangabe
Begin
WriteLn('Extended = Single: Ist Gleich? = ', CompilerVersion_e = CompilerVersion_s);
WriteLn;
WriteLn('Extended = Double: Ist Gleich? = ', CompilerVersion_e = CompilerVersion_d);
WriteLn;
WriteLn('Extended = Extended: Ist Gleich? = ', CompilerVersion_e = CompilerVersion_e);
WriteLn;
WriteLn('Extended = OHNE Typ: Ist Gleich? = ', CompilerVersion_e = CompilerVersion_o);
WriteLn;
WriteLn('SizeOf(CompilerVersion_e) = ', SizeOf(CompilerVersion_e));
WriteLn('SizeOf(CompilerVersion_s) = ', SizeOf(CompilerVersion_s));
WriteLn('SizeOf(CompilerVersion_d) = ', SizeOf(CompilerVersion_d));
WriteLn('SizeOf(CompilerVersion_o) = ', SizeOf(CompilerVersion_o));
ReadLn;
End;
Inndiesem Fall (
34.1) ist:
(Extended = Single) --->
False
(Extended = Single) --->
False
(Extended = Double) --->
True
(Extended = Extended) --->
True
(Extended = Ohne Typ) --->
True // Der Compiler verwendet hier automatisch
Double
Warum? Weil die Dezimalzahl 34.1 binär nicht exakt darstellbar ist und je nach Real-Type intern „ein bißchen“ anders aussieht.
Ändern wir die Konstanten jeweils auf
34, so sieht es ganz anders aus: Alle Vergleiche liefern
True, aber für die nicht-typisierte Konstante hat der Compiler (XE5) den Datentype
Byte gewählt.
Fazit: Um das Ergebnis des Vergleichs nicht dem Zufall & der Compilerversion zu überlassen, sollten wir die Konstante durch Typisierung eindeutig festlegen.
Gruß, Andreas