@dummzeuch
Es ist zu kompliziert, dass der Typ exakt das speichert was man dem zugewiesen hat? Das ist nicht höchtens sondern genau der Vorteil dieser Implementierung. So gut wie keine Veränderung der zugewiesenen Daten (bis auf die allgemeine Problem mit den Fließkommazahlen).
Es geht hier auch nicht darum ein höchst exakt rechnendes System vorzustellen, sondern nur einen Typen, der so genau ist wie Delphi selber rechnet aber mit Dimensionen/Einheiten umgehen kann.
Aber man kann es ja auch wie folgt deklarieren:
Delphi-Quellcode:
TValueType = Extended;
TMassUnit = (Undefined, Gram, Kilogram, Milligram, Tonne);
TMass =
record
private
FValue: TValueType;
// Wert
FUnit: TMassUnit;
// Einheit
public
constructor Create(AValue: TValueType; AUnit: TMassUnit);
property Value: TValueType
read FValue;
property &
Unit: TMassUnit
read FUnit;
private
function AsBaseUnit(): TValueType;
function AsBaseNumericType(AUnit: TMassUnit);
public
property Grams: TValueType
index TMassUnit.Gram
read AsBaseNumericType;
property Kilograms: TValueType
index TMassUnit.Kilogram
read AsBaseNumericType;
property Milligrams: TValueType
index TMassUnit.Milligram
read AsBaseNumericType;
property Tonnes: TValueType
index TMassUnit.Tonne
read AsBaseNumericType;
end;
dann implementierst du einen gaaaaaanz genauen Float-Type und tauscht den dort gegen Extended aus.
PS
Achja, ich vergaß noch einen (in meinen Augen) Vorteil:
Wenn man sich beim debuggen die lokalen Variablen anschaut, dann erscheint dort z.B.:
Finde ich persönlich eingängiger, als wenn dort lediglich
steht (die basiseinheit ist ja Kilogramm)
Und wenn man dann noch
ToString()
implementiert, dann ist es doch auch schön wenn dort
15g ausgegeben wird und eben nicht
0,015kg, eben immer so wie man es der Variablen auch zugewiesen hat.