Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Maßeinheiten als Typen (https://www.delphipraxis.net/198184-masseinheiten-als-typen.html)

Ghostwalker 11. Okt 2018 06:54

Maßeinheiten als Typen
 
Moinmoin,

da hier Unittests generieren die Frage aufgekommen ist, ob das Konzept, das als eigene Typen zu implementieren, stell ich hier mal die Frage nach Alternativen (schließlich kann auch ein SE mal irren).

Dabei ist das ganze als Grundstock für ein größeres Bibleotheks-Projekt gedacht. Dabei gibts natürlich einige Anforderungen:

1. Die einzelnen Typen sollen sicher und eindeutig sein.

Gemeint ist, das, wenn man das ganze als Parameter an eine Methode übergibt, keine andere Maßeinheit
übergeben werden kann

Beispiel:

Delphi-Quellcode:
   Procedure TuWas(const a:gramm);
Wenn versucht wird, hier Kilogram zu übergeben, soll der Compiler meckern.

2. Rechenoperationen sollen möglich sein. D.h. Addition, Subtraktion, Division und Multiplikation
3. Vergleichsoperation sollen auch möglich sein.

4. Eine Möglichkeit, von einer Maßeinheit in eine andere Maßeinheit zu konvertieren/umzurechnen

Wärend der Konzeptions und Tüftelphase (:)) bin ich auch auf das ein oder andere Problem gestoßen:

a) Klassen funktionieren hier nicht

Das größte Manko hier ist, das man keine Operatoren in Klassen definieren kann. Ein zweites, wenn auch
weniger wichtiges Manko ist, das Klassen explizit erzeugt werden müssen.

b) Records können nicht wirklich vererbt werden

Ansonsten hätte man einen "Basistypen" geschaffen, und den Rest einfach davon abgeleitet, so das
man das ganze mit weniger Aufwand umsetzen hätte können.

c) Kein wirkliches forwarding bei Records

Da man Records nur mit Zeigern forwarden kann, müssen einiges an Operatoren an ungewöhnlicher Stelle
implementiert werden. D. h. dass zu Beispiel der Add-Operator für Gramm+Kilogram bei Kilogram implementiert
wird, obwohl der Rückgabewert Gramm ist.

Daher der Ansatz, für jede Maßeinheit einen entsprechenden Record schaffen.

Wenn jemand einen alternativen Ansatz hat, immer her damit :)

Schokohase 11. Okt 2018 07:09

AW: Maßeinheiten als Typen
 
Dann erklär doch was die Problematik ist, wenn du ein Gewicht mit unterschiedlichen Einheiten übergibst.

Ich sehe da eigentlich kein Problem und bin daher der Meinung, dass ein Typ für Gewicht ausreicht und du keine Aufsplittung in Gramm, Kilogramm, Tonne Typen benötigst.

Ghostwalker 11. Okt 2018 07:46

AW: Maßeinheiten als Typen
 
Genaugenommen gibts 2:

1. Beispiel

Delphi-Quellcode:
Procedure Tuwas(const gramm:integer);overload;
Procedure Tuwas(const kilogram:integer);overload;
das tut so nicht, da der Compiler meint es wären die gleichen Parameter.

2. Beispiel

Delphi-Quellcode:
Procedure TuwasAnderes(const gramm:integer;const Kilogramm:integer);
Hier könnte ich z.B. problemlos auch Tonnen übergeben, was u.U. zu recht...interresanten Problemen führen kann.
Mit entsprechenden Typen kann ich sicherstellen, das dort, wo Gramm als Parameter erwartet wird, auch nur Gramm übergeben werden können.

3. Angenehmer Nebeneffekt

Delphi-Quellcode:
var
  a : Gramm;
  b : Kilogramm;
  erg : Gramm;

begin
  a := 10;
  b := 10;
  erg := a+b; //<-- Ergibt 10010 Gramm !
end;
Würde ich hier z.B. einfach integer nehmen, könnte man das Ergebnis in die Tonne treten.

Schokohase 11. Okt 2018 07:54

AW: Maßeinheiten als Typen
 
Das ist die Begründung dafür, warum du einen Typen für Gewicht benötigst, aber noch nicht die Begründung dafür, warum du mehrere Typen für Gewicht benötigst.

Delphi-Quellcode:
procedure Tuwas( const gewicht: TWeight );
begin
  ...
end;
Und verwenden so
Delphi-Quellcode:
begin
  Tuwas( TWeight.FromKilograms( 10 ) );
  Tuwas( TWeight.FromGrams( 10 ) );
  Tuwas( TWeight.FromTons( 10 ) );
end;
PS Als kleines Beispiel sei gennant, dass die Geschwindigkeit als Weg pro Zeit definiert ist und nicht als Meter pro Sekunde. Jede Geschwindigkeit kann auch als Meter pro Sekunde dargestellt werden und trotzdem gilt das auch wenn der Weg in Kilometer angegeben ist und die Zeit in Nanosekunden.

Ghostwalker 11. Okt 2018 08:11

AW: Maßeinheiten als Typen
 
und woher weis Tuwas, was er nun übergeben bekommen hat ? :)

Wenn die Methode nur mit bestimmte Einheiten arbeiten soll, hab ich hier nur die Möglichkeit, das über einen weiteren Parameter (nämlich die Einheit) und unterscheidet dann diese innerhalb der Methode.

oder

Es gibt für die entsprechenden Einheiten, entsprechende Überladungen.

hmmmm...


Natürlich könnte man in TWeight z.B. noch einen zusätzlichen wert für die Einheit mitführen. Aber letztlich würde das keine Vorteil bringen. Die Methoden und Operatoren müssten ja trotzdem die Einheiten unterscheiden.

bernau 11. Okt 2018 08:22

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1415473)
und woher weis Tuwas, was er nun übergeben bekommen hat ? :)

Wenn die Methode nur mit bestimmte Einheiten arbeiten soll, hab ich hier nur die Möglichkeit, das über einen weiteren Parameter (nämlich die Einheit) und unterscheidet dann diese innerhalb der Methode.

oder

Es gibt für die entsprechenden Einheiten, entsprechende Überladungen.

"TuWas" wurde TWeight übergeben. Mehr muss "Tuwas" nicht wissen. TWeight ist ein Record welches ein Value mit der Einheit (z.B. "Gramm") besitzt. Über die Funktionen "FromKilograms( 10 )" wird automatisch in Gramm umgerechnet. So mache ich das auch seit einiger Zeit, seit ich Operatoren in Records kennen gelernt habe. Ich mache daraus noch ein "Property asKilogram" somit kann man in beide Richtungen arbeiten.

Das ergibt dann sowas wie

Delphi-Quellcode:
var
  a:TWeight;
  b:TWeight;
begin
  a.asKilogram = 10;
  b.asGramm = 10;
  TuWas(a+b); // 1010gramm werden übergeben
end;

Ghostwalker 11. Okt 2018 08:26

AW: Maßeinheiten als Typen
 
Soweit schon richtig.

Und was machst du wenn Tuwas nur Gramm und Kilogramm verarbeiten soll nicht aber Tonnen oder Milligram ?

Wie ich grad oben erweitert hab, kann Tuwas das ganze nicht unterscheiden.

TigerLilly 11. Okt 2018 08:31

AW: Maßeinheiten als Typen
 
Hilft dir sowas?

Code:
Type
  TKilogramm= type of Integer;
  TGramm = type of integer;
http://docwiki.embarcadero.com/RADSt...%A4t_von_Typen

TiGü 11. Okt 2018 08:36

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1415460)
1. Die einzelnen Typen sollen sicher und eindeutig sein.

Gemeint ist, das, wenn man das ganze als Parameter an eine Methode übergibt, keine andere Maßeinheit
übergeben werden kann

Beispiel:

Delphi-Quellcode:
   Procedure TuWas(const a:gramm);
Wenn versucht wird, hier Kilogram zu übergeben, soll der Compiler meckern.

Vorweg:
Ich empfehle eine kurze Recherche bei Wikipedia zu Maßeinheiten, Vorsätzen und Einheitensystem zur Auffrischung.
Möglich wäre auch, dass du dir mal anschaust wie das die Delphi RTL für System.TimeSpan.TTimeSpan regelt.

Es ist mir beim Überfliegen dieses und des anderen Threads nicht ganz klar geworden, ob das mit den Gewicht nur ein Beispiel/Analogie ist oder du wirklich mit Gewichtsangaben arbeiten musst.

Nehmen wir mal an, es geht wirklich um Gewicht, also du willst die physikalische Maßeinheit für die Masse in einer bestimmten Gravation beziffern:
Gramm, Kilogramm, Tonne (1000 kg), Kilotonne (1000 * 1000 kg) sind keine verschiedenen Maßeinheiten.
Es bezieht sich immer auf ein und dasselbe mit verschiedenen Vorsätzen für Maßeinheiten.
Die SI-Basiseinheit für Masse ist das Kilogramm. Ein Gramm ist ein Tausendstel Kilogramm. Soweit bekannt, nix neues.
Schaffe dir einfach einen einzigen konkreten Basisdatentyp, bspw. mit Gramm und gebe ihm die entsprechenden Methoden.

Delphi-Quellcode:
type
  TKilogramm = type UInt64;
  TTonne = type UInt64;

  TKilogrammHelper = record helper for TKilogramm
    function ToString: string;
  end;

  TTonneHelper = record helper for TTonne
    function ToString: string;
  end;

  TGramm = type Double;

  TGewicht = record
  strict private
    FDasRichtigeGewichtInGrammAlsFliesskommazahl: TGramm;
    // Warum Fliesskomma? Vielleicht willst du auch mal Milli- und/oder Mikrogramm verarbeiten.
    // Man kann natürlich auch mit einen UInt32 oder UInt64 als Basis arbeiten, dann muss das aber im Vorfeld klar sein, welche die kleinste Größe ist.
    // Bei einen Kuchenrezept bspw. ist höchstwahrscheinlich die kleinste Gewichtsangabe sowas wie "eine Prise Salz/ein halbes Gramm".
  private
    // ggf. mit richtigen Gettern und Settern versehen
    property RawValue: TGramm read FDasRichtigeGewichtInGrammAlsFliesskommazahl write FDasRichtigeGewichtInGrammAlsFliesskommazahl;
  public
    class function Add(const A, B: TGewicht): TGewicht; static;
    function AsKilogramm: TKilogramm;
    // Hier kommen nur sinnvolle Werte größer null bei raus, wenn die interne Variable vor dem Komma mehr als 1000 groß ist.
    function AsTonne: TTonne;
    // Hier kommen nur sinnvolle Werte größer null bei raus, wenn die interne Variable vor dem Komma mehr als 1000 * 1000 groß ist.
  end;

implementation

{ TGewicht }

class function TGewicht.Add(const A, B: TGewicht): TGewicht;
begin
  Result.RawValue := A.RawValue + B.RawValue;
end;

function TGewicht.AsKilogramm: TKilogramm;
begin
  Result := Round(RawValue / 1000);
end;

function TGewicht.AsTonne: TTonne;
begin
  Result := Round(RawValue / 1000 * 1000);
end;

{ TKilogrammHelper }

function TKilogrammHelper.ToString: string;
begin

end;

{ TTonneHelper }

function TTonneHelper.ToString: string;
begin

end;

bernau 11. Okt 2018 08:38

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1415477)
Soweit schon richtig.

Und was machst du wenn Tuwas nur Gramm und Kilogramm verarbeiten soll nicht aber Tonnen oder Milligram ?

Wie ich grad oben erweitert hab, kann Tuwas das ganze nicht unterscheiden.

"TuWas" muss es ja auch nicht unterscheiden. "TuWas" erhält immer nur den Wert "TWeight".

:glaskugel: Aber du wirst deinen Grund haben. Interessieren würde es mich schon, weshalb z.B. nur "Tonnen" verwendet werden soll und alle anderen nicht. Gewicht ist Gewicht, egal welche Maßzahl verwendet wird.

Schokohase 11. Okt 2018 08:38

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1415477)
Und was machst du wenn Tuwas nur Gramm und Kilogramm verarbeiten soll nicht aber Tonnen oder Milligram ?

Nenne mir einen Grund warum dieses notwendig ist. Ich kann da keinen Grund erkennen.

Wird eine Formel anders, wenn du statt mit 100kg einfach mit 0,1t rechnest?

Oder würde die Formel nicht eher so aussehen
Delphi-Quellcode:
class operator TDuration.Divide( const a: TLength; const b: TDuration ): TSpeed;
begin
  Result := TSpeed.FromMetersPerSecond( a.Meters / b.Seconds );
end;
Oder um bei deinem Beispiel zu bleiben
Delphi-Quellcode:
function Tuwas( const gewichtA, gewichtB : TWeight ): Currency;
begin
  // Preis für A = 20 Euro pro Kilogramm
  // Preis für B = 30 Euro pro Gramm
  Result := 20 * gewichtA.Kilograms + 30 * gewichtB.Grams;
end;
Warum sollte es eine gesonderte Rolle spielen ob ich den Wert in Tonnen oder Kilogramm übergeben habe? In der Berechnung werden die korrekten Einheiten verwendet und nur das zählt.

Ghostwalker 11. Okt 2018 08:41

AW: Maßeinheiten als Typen
 
hmm...ok..mit Type of macht es zumindest schon mal keine Probleme bei überladenen Methoden.

Aber wie bastel ich dann entsprechende Operatoren ?

Fritzew 11. Okt 2018 08:46

AW: Maßeinheiten als Typen
 
Ich würde sagen, Du machst es Dir zu schwer.
Bei uns gibt es die gleiche Problematik. Allerdings versuchen wir das nicht innerhalb der Verarbeitung abzufangen.
Es gbt für jeden "Einheistfall" einen Basistypen. Bei uns für Länge, Flächen, Volumen, Gewicht, Winkel etc.
Der Basistyp muss halt Deinen gesamten Wertebereich der jeweiligen Einheit abfangen.
Umgewandelt wird nur zur Anzeige oder bei Lesen/Schreiben......
Das vereinfacht innerhalb des Programmes die ganze Rechnerei.
Wir haben Edits die den Basistyp bekommen und je nach Einstellung das in der jeweiigen Einheit anzeigt und annnimmt.
Alles einfach Testbar.

Uwe Raabe 11. Okt 2018 10:18

AW: Maßeinheiten als Typen
 
Unter Verwendung der Units System.ConvUtils und System.StdConvs kann man da recht einfach was zaubern:
Delphi-Quellcode:
type
  TGramm = type Double;
  TKilogramm = type Double;

  TWeight = record
  private
    FConv: TConvType;
    FValue: Double;
  public
    constructor Create(AValue: Double; AConv: TConvType);
    class operator Implicit(A: TWeight): TGramm; overload;
    class operator Implicit(A: TGramm): TWeight; overload;
    class operator Implicit(A: TWeight): TKilogramm; overload;
    class operator Implicit(A: TKiloGramm): TWeight; overload;
    property Conv: TConvType read FConv write FConv;
    property Value: Double read FValue write FValue;
  end;

constructor TWeight.Create(AValue: Double; AConv: TConvType);
begin
  FValue := AValue;
  FConv := AConv;
end;

class operator TWeight.Implicit(A: TWeight): TGramm;
begin
  Result := Convert(A.Value, A.Conv, muGrams);
end;

class operator TWeight.Implicit(A: TGramm): TWeight;
begin
  Result := TWeight.Create(A, muGrams);
end;

class operator TWeight.Implicit(A: TWeight): TKilogramm;
begin
  Result := Convert(A.Value, A.Conv, muKilograms);
end;

class operator TWeight.Implicit(A: TKiloGramm): TWeight;
begin
  Result := TWeight.Create(A, muKilograms);
end;
Natürlich kannst du dir auch selbst deine Einheiten und Konvertierungen erstellen, aber es gibt halt mit den oben genannten Units schon einen vorgefertigten Mechanismus dafür.

Das Konvertieren geht dann über ein Cast auf TWeight:
Delphi-Quellcode:
procedure TuWas(const Value: TGramm); overload;
var
  K: TKiloGramm;
begin
  K := TWeight(Value);
  Writeln(Format('%1.3f g = %1.3f Kg', [Value, K]));
end;

procedure TuWas(const Value: TKiloGramm); overload;
var
  K: TGramm;
begin
  K := TWeight(Value);
  Writeln(Format('%1.3f Kg = %1.3f g', [Value, K]));
end;
Delphi-Quellcode:
var
  A: TKiloGramm;
  B: TGramm;
  C: TTonnen;
begin
  A := 50;
  B := 1500;
  TuWas(A);
  TuWas(B);
  TuWas(C); // Fehlermeldung: Doppeldeutiger überladener Aufruf von 'TuWas'
end;

Ghostwalker 11. Okt 2018 10:40

AW: Maßeinheiten als Typen
 
@Schokohase

Und wie stellst du sicher, das an Tuwas keine Tonnen übergeben werden, weil z.B. kein Preis dafür definiert ist ?

@Uwe

Naja...im Prinzip ists das gleiche, wenn ich alles in einen Typen reinschiebe. Außer das ich alles in einem Typen hab (der verdammt groß wird) hätte ich nicht wirklich was gewonnen. Die ganze Operator-Kombinationen müsst ich ja genauso implementieren und entsprechend testen.

Schokohase 11. Okt 2018 10:44

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1415494)
@Schokohase

Und wie stellst du sicher, das an Tuwas keine Tonnen übergeben werden, weil z.B. kein Preis dafür definiert ist ?

Ähm, du hast das Beispiel falsch verstanden. Da gibt es etwas, da kostet das Kilogramm 20 Euro. Und da gibt es etwas anderes da kostet das Gramm 30 Euro.

Wenn du davon 3 Trillionen Tonnen haben möchtest, dann lasse ich mir über den Typen das Gewicht in Kilogram geben und multipliziere das mit den 20 Euro oder ich lasse mir das über den Typen in Gramm geben und multipilziere das mit den 30 Euro (je nachdem).

Ghostwalker 11. Okt 2018 11:15

AW: Maßeinheiten als Typen
 
Ich glaub ich hab dich da schon richtig verstanden. Klar kann ich das umrechnen (von T in kg oder g). Wenn es aber keine T gibt (aus welchen Gründen auch immer), dann kann das Tuwas nicht unterscheiden.

Medium 11. Okt 2018 11:51

AW: Maßeinheiten als Typen
 
Ich würde sagen, dass dann die Unterscheidung nicht mehr im Verantwortungsbereich von TuWas() liegt, sondern bereits vorher erledigt werden muss. Nämlich direkt nach der Eingabe in der Glue-Logic des Forms, weil das der einzige Zeitpunkt sein sollte, zu dem diese Unterscheidung Sinn ergibt. Vor allem weil ja vermutlich erst über die Beschriftung im Formular deutlich wird welche Einheit letztlich eingegeben wird. Die Geschäftslogik sollte das nicht mehr interessieren dürfen. Das wäre so meine Interpretation zumindest.

bernau 11. Okt 2018 11:51

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1415503)
Wenn es aber keine T gibt (aus welchen Gründen auch immer), dann kann das Tuwas nicht unterscheiden.

Ich glaube wir tappen hier etwas im Dunkeln. Grundsätzlich ist es so, wenn es etwas in kg gibt, dann gibt es das auch in Tonnen. Es kann ja nicht sein, dass es von einem Artikel 100kg gibt, aber nicht 0,1Tonnen.

Ist es vielleicht so, dass es unterschiedliche Preise für kg und Tonnen gibt und du musst deshalb eine Unterscheidung machen. :glaskugel:

Hat irgendwie etwas von dem XY-Problem was Stevie in einem anderen Beitrag mal angesprochen hatte.

Schokohase 11. Okt 2018 11:59

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1415503)
Ich glaub ich hab dich da schon richtig verstanden. Klar kann ich das umrechnen (von T in kg oder g). Wenn es aber keine T gibt (aus welchen Gründen auch immer), dann kann das Tuwas nicht unterscheiden.

Ich frage dich genau nach diesen Gründen - warum sollte das so sein - denn nur wenn es dazu eine vernünftige Begründung gibt, dann lohnt es sich auch darüber nachzudenken, warum man etwas auseinanderreißt, was eigentlich zusammengehört.

Ansonsten nimmt man einen Typen für eine Einhait, dieser speichert den Wert so wie der als SI Einheit definiert ist (Gewicht-> Kilogramm, Länge->Meter, Temeraturdifferenz->Kelvin, usw.) und schafft sich einfache Zugriffsmöglichkeiten um diese dann beliebig umzurechnen.

Also
Delphi-Quellcode:
TWeight.FromTons(1).Grams
ergibt dann die Zahl 1000000.

Rollo62 11. Okt 2018 12:01

AW: Maßeinheiten als Typen
 
Zitat:

Es gbt für jeden "Einheistfall" einen Basistypen. Bei uns für Länge, Flächen, Volumen, Gewicht, Winkel etc.
Der Basistyp muss halt Deinen gesamten Wertebereich der jeweiligen Einheit abfangen.
Umgewandelt wird nur zur Anzeige oder bei Lesen/Schreiben......
Vollkommen richtig, so mache ich das auch :thumb:

Anlehnend an die SI Einheiten, in der i.d.R. auch zusammengesetzte Formeln berechnet werden, heist das die Typen rechnen immer richtig.
Lediglich bei der Ein- und Ausgabe will der "Mensch" halt gerne mal was anderes sehen :stupid:

Rollo

Stevie 11. Okt 2018 12:18

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1415488)
Unter Verwendung der Units System.ConvUtils und System.StdConvs kann man da recht einfach was zaubern:

Das ist dann leider unter Berücksichtigung der Umwandlung nutzlos:

Delphi-Quellcode:
var
  A: TKiloGramm;
  B: TGramm;
begin
  A := 50;
  B := A; // compiliert ohne irgendwelche Konvertierungen, dun dun dunnn :(

p80286 11. Okt 2018 13:13

AW: Maßeinheiten als Typen
 
@Ghostwalker
Vielleicht solltest Du ein wenig ausholen und uns sagen was der Hintergrund Deiner Frage ist.
Grundsätzlich würde ich mit einem Record arbeiten:
Delphi-Quellcode:
Type
  tEinheit=(mgr,gr,kg,ton);
  tMyrec=record
           Menge:integer;
           Einheit:tEinheit;
         end;
Gruß
K-H

Uwe Raabe 11. Okt 2018 13:33

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Stevie (Beitrag 1415519)

Das ist dann leider unter Berücksichtigung der Umwandlung nutzlos:

Delphi-Quellcode:
var
  A: TKiloGramm;
  B: TGramm;
begin
  A := 50;
  B := A; // compiliert ohne irgendwelche Konvertierungen, dun dun dunnn :(

Diese Verwendung war aber auch nicht in den vier Vorgaben des Posts aufgeführt.

Zitat:

1. Die einzelnen Typen sollen sicher und eindeutig sein.

Gemeint ist, das, wenn man das ganze als Parameter an eine Methode übergibt, keine andere Maßeinheit
übergeben werden kann

Beispiel:

Procedure TuWas(const a:gramm); Wenn versucht wird, hier Kilogram zu übergeben, soll der Compiler meckern.

2. Rechenoperationen sollen möglich sein. D.h. Addition, Subtraktion, Division und Multiplikation
3. Vergleichsoperation sollen auch möglich sein.

4. Eine Möglichkeit, von einer Maßeinheit in eine andere Maßeinheit zu konvertieren/umzurechnen
Punkt 1 ist gegeben, für Punkt 2 und 3 muss TWeight noch etwas erweitert werden und Punkt 4 liegt als Beispiel vor. Daß eine direkte Zuweisung einer TGramm-Variable an eine TKilogramm-Variable vom Compiler verboten sein soll, kann ich da nicht entdecken. Eine korrekte Zuweisung muss natürlich über TWeight erfolgen, aber das ist ja auch schon im Beispiel gezeigt.

Ghostwalker 12. Okt 2018 06:03

AW: Maßeinheiten als Typen
 
Das mit der direkten Zuweisung von verschiedenen Maßeinheiten ist eher Kontraproduktiv. Den dann wärs ja wieder möglich, bei Verwendung als Methoden-Parameter, bei Gramm, Kilogramm zu übergeben.

Das läst sich aber umgehen, in dem man statt Implizierter Typumwandlung die Explizite Variante wählt.

Was mich allerdings irretiert ist, wo der Vorteil liegen soll, das ganze in einem Typ zu handhaben.

@p80286
siehe 1 Post und Verweis auf anderen Thread :)

Ursprünglich wollte ich für jede Maßeinheit (als Beispiel hab ich Gewichte genommen) einen eigenen eigenen
Record definieren mit entsprechenden Operatoren und Convertierungen. Im anderen Thread ging es darum, ob man
entsprechende Unittests generieren kann. Dabei kamm die Frage auf, ob das wirklich das beste Design ist (also
einzelne Typen für Maßeinheiten), da es doch recht aufwendig ist. Da das ganze mit der Unittest-Frage nur indirekt zu tun hab, hab ich das ganze mal abgekapselt.

TiGü 12. Okt 2018 08:07

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1415562)
Ursprünglich wollte ich für jede Maßeinheit (als Beispiel hab ich Gewichte genommen) einen eigenen eigenen
Record definieren mit entsprechenden Operatoren und Convertierungen.

Das ist ja auch vollkommen okay.
Du musst nur verstehen das Kilogramm, Gramm, Mikrogramm, Nanogramm K E I N E verschiedenen Maßeinheiten sind.
Es ist immer ein und dieselbe Maßeinheit mit verschiedenen Vorsätzen.
Ich wiege gleichzeitig 100 kg = 100000 g = 100000000000000 ng.
Das kann man mit einem einzigen Typen abbilden.

Jumpy 12. Okt 2018 08:45

AW: Maßeinheiten als Typen
 
Ich hab gestern zufällig einen Vortrag (Java, sorry) gehört über eine "JSR-354 Money and Currency API".
Grundprinzip war in etwa, das Geld jeweils aus einem Betrag und einer Währung besteht und alles jeweils Objekte sind, mit diversen Eigenschaften und Methoden. Dazu gibt es Umrechnungsobjekte von Währungen usw.

Was ich damit sagen will: Wenn man es schon kompliziert und ausführlich machen will, mit viel Overhead, dann aber auch alles richtig als Objekte abgebildet mit Typsicherheit usw. (auch wenn Delphi nicht Java ist, kann man sich da ja was abgucken).

Rollo62 12. Okt 2018 09:04

AW: Maßeinheiten als Typen
 
Zitat:

Es ist immer ein und dieselbe Maßeinheit mit verschiedenen Vorsätzen.
Jein, das stimmt zwar in den meisten Fällen.
Also Kg, ng, gr, m, cm, dm sind nur verschiedene Faktoren, das ist leicht.

Aber es gibt auch Ausreisser, z.B. bei Temperatur (°C, °F, °K),
das muss man mit Offset und Faktor arbeiten.

Oder bei Winkeln und Längen in diversen Darstellungsformen, z.B. der worst case ist wohl in USA mit der grässlichen inch-feet Darstellung und Brüchen derselben.


Rollo

Schokohase 12. Okt 2018 09:15

AW: Maßeinheiten als Typen
 
@Rollo62

Egal wie komplex die Umrechung ist, die Bedeutung bleibt aber immer dieselbe, egal in welcher Dimension ich diese Einheit darstelle/angebe.

Es wird nicht heißer oder kälter wenn ich die Temperatur(-Differenz) in Celsius, Kelvin oder Fahrenheit angebe.

Es wird nicht schwerer oder leichter wenn ich das Gewicht in Kilogramm, Tonnen oder Mikrogramm angebe.

Der TE hat es aber bislang nicht geschafft auch nur ansatzweise eine Begründung zu liefern, warum er diese Aufsplittung einer Einheit in unterschiedliche Dimensions-Typen als nötig erachtet. Es kommt nur ein "ja, wenn man das mal braucht".

JasonDX 12. Okt 2018 09:17

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Rollo62 (Beitrag 1415586)
Zitat:

Es ist immer ein und dieselbe Maßeinheit mit verschiedenen Vorsätzen.
Jein, das stimmt zwar in den meisten Fällen.
Also Kg, ng, gr, m, cm, dm sind nur verschiedene Faktoren, das ist leicht.

Aber es gibt auch Ausreisser, z.B. bei Temperatur (°C, °F, °K),
das muss man mit Offset und Faktor arbeiten.

Oder bei Winkeln und Längen in diversen Darstellungsformen, z.B. der worst case ist wohl in USA mit der grässlichen inch-feet Darstellung und Brüchen derselben.

Es ist aber immer die selbe physikalische Größe. Deswegen glaube ich dass die weiter oben vorgeschlagene Möglichkeit, orientiert an System.TimeSpan.TTimeSpan, die sinnvollste Lösung ist: Sie dokumentiert um welche Physikalische Größes es sich handelt (Und garantiert dass nicht Sekunden statt Gramm übergeben werden), inklusive der exakten Maßeinheit (es wird vermieden dass ein Wert als "meter" angegeben, aber als "millimeter" interpretiert wird), und erlaubt flexible Konvertierungen (Bei Gewicht kann dies z.B. auch Pfund etc. beinhalten, bei Geschwindigkeit m/s, kmh und mph, und zwischen Kelvin, Celsius und Fahrenheit zu konvertieren ist auch kein Problem).
Einzig Operatoren würde ich außen vor lassen. Addition und Subtraktion sind vllt. noch machbar, aber bei Multiplikation&Division wirds schwierig: Bspw. muss das Multiplikationsergebnis aus Spannung und Stromfluss vom Divisionsergebnis aus Drehmoment durch Zeit subtrahierbar sein.

Guava macht das ganze übrigens ähnlich.

TiGü 12. Okt 2018 09:27

AW: Maßeinheiten als Typen
 
Plot Twist: Das eigentliche Grundproblem ist etwas ganz anderes und kann mit drei Zeilen erschlagen werden! :twisted:

Rollo62 12. Okt 2018 09:32

AW: Maßeinheiten als Typen
 
Natürlich ist es die gleiche Größe, das schreibe ich ja schon ganz unten.

Aber der Unterschied kann sein ob diese in einer Variablen gespeichert werden kann, oder ob ich mehrere brauche um alle Aspekte abzudecken.

Wenn ich es nur z.B. in Double speichere können dabei Informationenen verloren gehen, wie z.B. beim Winkel welcher Quadrant, o.ä.

Rollo

Schokohase 12. Okt 2018 09:43

AW: Maßeinheiten als Typen
 
@Rollo62

Bzgl. der Winkel und der Quadranten:

Ein Winkel von 60° ist ein Winkel von 60°. Punkt.
Genauso wie 1 Stunde auch 1 Stunde ist.

Wenn du beim Winkel noch den Quadranten noch ins Spiel bringst, dann ist es das gleiche, als wenn du bei der Zeit noch die Information „nach Mitternacht in Wladiwostok“ ins Spiel bringst. Es ist dann eben nicht mehr einfach nur ein Winkel oder einfach nur eine Zeit.

Jumpy 12. Okt 2018 09:52

AW: Maßeinheiten als Typen
 
Ein Winkel von 60° im Gradmaß ist ein Winkel von 60° im Gradmaß. So wird ein Punkt draus.

Schokohase 12. Okt 2018 10:08

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Jumpy (Beitrag 1415597)
Ein Winkel von 60° im Gradmaß ist ein Winkel von 60° im Gradmaß. So wird ein Punkt draus.

Oh, ich nahm wohl fälschlicherweise an, dass ° für Grad steht und im Bezug zu einem Winkel somit einen Winkel im Grandmaß kennzeichnet.

Da will ich mich natürlich vielmals für entschuldigen.

Rollo62 12. Okt 2018 10:11

AW: Maßeinheiten als Typen
 
Es gibt Systeme die nur Winkel von 0 ... 90° liefern, wo man dann je nach Laune interpretieren kann in welchen Quadranten die liegen.

Ist auch egal, muss dich nicht überzeugen das es Grenzfälle gibt.

Schokohase 12. Okt 2018 10:20

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Rollo62 (Beitrag 1415605)
Es gibt Systeme die nur Winkel von 0 ... 90° liefern, wo man dann je nach Laune interpretieren kann in welchen Quadranten die liegen.

Ist auch egal, muss dich nicht überzeugen das es Grenzfälle gibt.

Es gibt ja auch Wladiwostok und dort auch Mitternacht. Nur weil es etwas gibt gehört es aber nicht überall mit hinein, sondern ist eine Kombination aus mehreren Informationen.

Ein Winkelmesser kann auch nicht den Quadranten bestimmen und trotzdem gibt es einen Winkelmesser. Und das Ergebnis von dem Winkelmesser ist dann ein Winkel.

Wenn der Quadrant benötigt wird (und ich bezweifle doch gar nicht, dass das auch benötigt werden kann), dann ist das eine zusätzliche räumliche Information zum Winkel die dann separat gespeichert werden muss, oder man macht sich dafür einen eigenen Typen, der dann Winkel und Quadrant beinhaltet.

Ghostwalker 12. Okt 2018 11:41

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von TiGü (Beitrag 1415578)
Du musst nur verstehen das Kilogramm, Gramm, Mikrogramm, Nanogramm K E I N E verschiedenen Maßeinheiten sind.
Es ist immer ein und dieselbe Maßeinheit mit verschiedenen Vorsätzen.
Ich wiege gleichzeitig 100 kg = 100000 g = 100000000000000 ng.

Ok, einigen wir uns darauf, das es alles Gewichtsmaßeinheiten sind. Aber es sind sehr wohl unterschiedliche Maßeinheiten für Gewicht. Ansonsten wäre 1 kg = 1 g = 1ng.

Du wirst mir aber sicher zustimmen, das es sehr wohl einen Unterschied macht, ob dir 100 g oder 100 t auf den Kopf fallen.



@Jumpy

Bin ich voll bei dir, was die Objekte betrifft, aber die mögen in Delphi nunmal keine Operatoren. Mal ganz davon abgesehen (das is aber rein eine persönlicher Faible), das man sie explizit erst erzeugen muss.

Schokohase 12. Okt 2018 11:49

AW: Maßeinheiten als Typen
 
@Ghostwalker

Diese Zusätze wie Milli-, Centi-, Dezi- oder auch Kilo- stehen ganz simpel für einfache Faktoren. Nicht mehr und nicht weniger. Es bleibt ein Gewicht.

1 Kilo-Gramm => 1 * 1000 Gramm => 1000 Gramm
0,1 Kilo-Gramm => 0,1 * 1000 Gramm => 100 Gramm

Eigentlich sind 0,1kg und 100g gleich und du willst jetzt, dass 100g ein zulässiger Wert ist, aber 0,1kg ist nicht zulässig?

Dann kann ich dir tatsächlich nicht mehr helfen, denn nun verlassen wir endgültig die rationale Basis für eine Diskussion.

TiGü 12. Okt 2018 12:15

AW: Maßeinheiten als Typen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1415611)
Zitat:

Zitat von TiGü (Beitrag 1415578)
Du musst nur verstehen das Kilogramm, Gramm, Mikrogramm, Nanogramm K E I N E verschiedenen Maßeinheiten sind.
Es ist immer ein und dieselbe Maßeinheit mit verschiedenen Vorsätzen.
Ich wiege gleichzeitig 100 kg = 100000 g = 100000000000000 ng.

Ok, einigen wir uns darauf, das es alles Gewichtsmaßeinheiten sind. Aber es sind sehr wohl unterschiedliche Maßeinheiten für Gewicht. Ansonsten wäre 1 kg = 1 g = 1ng.

Du wirst mir aber sicher zustimmen, das es sehr wohl einen Unterschied macht, ob dir 100 g oder 100 t auf den Kopf fallen.

Wie ich bereits in Beitrag #9 schrieb, fehlt hier grundlegendes Wissen bezüglich folgender Themen:

https://de.wikipedia.org/wiki/Ma%C3%9Feinheit
https://de.wikipedia.org/wiki/Vors%C...C3%9Feinheiten
https://de.wikipedia.org/wiki/Intern...inheitensystem

Du unterscheidest beim Programmieren doch auch nicht, ob die Zahl Dezimal, Hexadezimal, Binär oder Octal dargestellt wird, oder?


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:18 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz