AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Maßeinheiten als Typen

Ein Thema von Ghostwalker · begonnen am 11. Okt 2018 · letzter Beitrag vom 18. Okt 2018
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von TigerLilly
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.241 Beiträge
 
Delphi 12 Athens
 
#1

AW: Maßeinheiten als Typen

  Alt 11. Okt 2018, 08:31
Hilft dir sowas?

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

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Maßeinheiten als Typen

  Alt 11. Okt 2018, 08:41
hmm...ok..mit Type of macht es zumindest schon mal keine Probleme bei überladenen Methoden.

Aber wie bastel ich dann entsprechende Operatoren ?
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Maßeinheiten als Typen

  Alt 11. Okt 2018, 08:46
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.
Fritz Westermann
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.639 Beiträge
 
Delphi 12 Athens
 
#4

AW: Maßeinheiten als Typen

  Alt 11. Okt 2018, 10:18
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;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.045 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#5

AW: Maßeinheiten als Typen

  Alt 11. Okt 2018, 12:18
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 :(
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Maßeinheiten als Typen

  Alt 11. Okt 2018, 13:13
@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
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.639 Beiträge
 
Delphi 12 Athens
 
#7

AW: Maßeinheiten als Typen

  Alt 11. Okt 2018, 13:33

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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Maßeinheiten als Typen

  Alt 12. Okt 2018, 06:03
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.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: Maßeinheiten als Typen

  Alt 11. Okt 2018, 10:40
@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.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#10

AW: Maßeinheiten als Typen

  Alt 11. Okt 2018, 10:44
@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).
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz