![]() |
AW: Einheiten parsen
Zitat:
![]() Im Prinzip könnte man so ein Einheitensystem auch anwendungspezifisch festlegen, aber es ist vermutlich clever SI-Einheiten zu benutzen. Die "zusammengesetzt Einheiten" sind nach der Terminologie dann abgeleite Einheiten. |
AW: Einheiten parsen
Ja, man kommt dann nicht drumherum diese Basiseinheiten mit allen ihren Ausprägungen (m, cm => 1/100m, km => 1000m, s, min => 60s, h => 3600s, ...) als Typ zu definieren.
Dann benötigt man einen weiteren Typen, der mit den zusammengesetzten Basiseinheiten umgehen kann. Da hat man dann Basis-Einheiten im Zähler und im Nenner, die man dann auch wegkürzen kann, damit aus
Code:
werden kann.
60 Meter/Sekunde * 60 Sekunden = 3600 Meter
Code:
Spannend wird es dann eben noch, wenn man unterschiedliche Einheiten aus der gleichen Familie hat:
Wert1 => Wert: 60, Einheit Zähler: [Meter], Einheit Nenner: [Sekunde]
Wert2 => Wert: 60, Einheit Zähler: [Sekunde], Einheit Nenner: [] Ergebnis => Wert 3600, Einheit Zähler: [Meter], Einheit Nenner: []
Code:
Wert1 => Wert: 60, Einheit Zähler: [KilometerMeter], Einheit Nenner: [Stunde]
Wert2 => Wert: 60, Einheit Zähler: [Sekunde], Einheit Nenner: [] Ergebnis => Wert 1, Einheit Zähler: [KiloMeter], Einheit Nenner: [] |
AW: Einheiten parsen
Zitat:
Beim Einlesen werden alle Werte und Einheiten zu den Basiseinheiten normalisiert. Beim Ausgeben muss man gucken, wie die Anforderungen sind. |
AW: Einheiten parsen
Kann man da nicht mit Sets oder irgendwie bitweise was rechen, sonst tippt man sich ja den Wolf? (und sind hier gerade mal 9 mögliche Kombinationen). Die usNone müssen natürlich noch ausgefüllt werden.
Delphi-Quellcode:
type TUnitStyle = (usNone, usKNdivM3, usKNdivM2, usKNdivM, usKNMdivM, usKNM, usKN, usM3, usM2, usM); function GetUnitPlus(const A, B: TUnitStyle): TUnitStyle; begin if A = B then Result := A else Result := usNone; end; function GetUnitMinus(const A, B: TUnitStyle): TUnitStyle; begin if A = B then Result := A else Result := usNone; end; function GetUnitDiv(const A, B: TUnitStyle): TUnitStyle; begin Result := usNone; case A of usKNdivM3: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKNdivM2: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKNdivM: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKNMdivM: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKNM: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKN: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usM3: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usM2: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usM: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; end; end; function GetUnitMult(const A, B: TUnitStyle): TUnitStyle; begin Result := usNone; case A of usKNdivM3: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKNdivM2: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKNdivM: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKNMdivM: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKNM: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usKN: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usM3: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usM2: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; usM: begin case B of usKNdivM3: Result := usNone; usKNdivM2: Result := usNone; usKNdivM: Result := usNone; usKNMdivM: Result := usNone; usKNM: Result := usNone; usKN: Result := usNone; usM3: Result := usNone; usM2: Result := usNone; usM: Result := usNone; end; end; end; end; end. |
AW: Einheiten parsen
Zitat:
Zum Beispiel mit den Array aus Beitrag ![]() EDIT: Hast du das Ganze per Hand heruntergeschrieben? :pale: |
AW: Einheiten parsen
Zitat:
Deinen Ansatz #9 hab ich nich kapiert. Montags kapier ich noch weniger als sonst.. Kannst nochmal etwas erläutern? |
AW: Einheiten parsen
Deine Basiseinheiten definierst du weiter als Aufzählungstyp:
Delphi-Quellcode:
Die zusammengesetzten Einheiten lassen sich auch in Exponentenschreibweise aufschreiben. Die Exponenten kannst du dann einfach in einem Array speichern.
type
TFundamentalUnit = (fuKN, fuM);
Delphi-Quellcode:
type
TDerivedUnit = array[fuKN..fuM] of Integer.
Zum Beispiel die Multiplikation kann man nun ganz einfach auf eine Addition der Array-Einträge abbilden (quasi mit den Rechenregeln für Potenzen):
Ich hoffe das ist verständlicher :wink: |
AW: Einheiten parsen
Geht sehr gut. Danke Robert. :thumb:
Delphi-Quellcode:
type
TUnitBase = (fuKN, fuM); TUnitStyle = (usNone, usKNdivM3, usKNdivM2, usKNdivM, usKNM, usKN, usM3, usM2, usM); TUnits = class private FItems: array[usNone..usM, fuKN..fuM] of integer; function GetValues(Index: TUnitStyle): double; function GetAsString(Index: TUnitStyle): string; public property Values[Index: TUnitStyle]: double read GetValues; property AsString[Index: TUnitStyle]: string read GetAsString; function GetPlus(const A, B: TUnitStyle): TUnitStyle; function GetMinus(const A, B: TUnitStyle): TUnitStyle; function GetDiv(const A, B: TUnitStyle): TUnitStyle; function GetMult(const A, B: TUnitStyle): TUnitStyle; constructor Create; end; var Form1: TForm1; implementation {$R *.dfm} { TUnits } constructor TUnits.Create; begin FItems[usNone, fuKN] := 0; FItems[usNone, fuM] := 0; FItems[usKNdivM3, fuKN] := 1; FItems[usKNdivM3, fuM] := -3; FItems[usKNdivM2, fuKN] := 1; FItems[usKNdivM2, fuM] := -2; FItems[usKNdivM, fuKN] := 1; FItems[usKNdivM, fuM] := -1; FItems[usKNM, fuKN] := 1; FItems[usKNM, fuM] := 1; FItems[usKN, fuKN] := 1; FItems[usKN, fuM] := 0; FItems[usM3, fuKN] := 0; FItems[usM3, fuM] := 3; FItems[usM2, fuKN] := 0; FItems[usM2, fuM] := 2; FItems[usM, fuKN] := 0; FItems[usM, fuM] := 1; end; function TUnits.GetValues(Index: TUnitStyle): double; begin Result := IntPower(FItems[Index, fuKN], FItems[Index, fuM]); end; function TUnits.GetAsString(Index: TUnitStyle): string; begin case Index of usKNdivM3: Result := 'kN/m3'; usKNdivM2: Result := 'kN/m2'; usKNdivM: Result := 'kN/m'; usKNM: Result := 'kNm'; usKN: Result := 'kN'; usM3: Result := 'm3'; usM2: Result := 'm2'; usM: Result := 'm'; else Result := ''; end; end; function TUnits.GetPlus(const A, B: TUnitStyle): TUnitStyle; begin if A = B then Result := A else Result := usNone; end; function TUnits.GetMinus(const A, B: TUnitStyle): TUnitStyle; begin if A = B then Result := A else Result := usNone; end; function TUnits.GetMult(const A, B: TUnitStyle): TUnitStyle; var I: TUnitStyle; KN, M: integer; begin Result := usNone; KN := FItems[A, fuKN] + FItems[B, fuKN]; M := FItems[A, fuM] + FItems[B, fuM]; for I := Low(TUnitStyle) to High(TUnitStyle) do if (KN = FItems[I, fuKN]) and (M = FItems[I, fuM]) then begin Result := I; Break; end; end; function TUnits.GetDiv(const A, B: TUnitStyle): TUnitStyle; var I: TUnitStyle; KN, M: integer; begin Result := usNone; KN := FItems[A, fuKN] - FItems[B, fuKN]; M := FItems[A, fuM] - FItems[B, fuM]; for I := Low(TUnitStyle) to High(TUnitStyle) do if (KN = FItems[I, fuKN]) and (M = FItems[I, fuM]) then begin Result := I; Break; end; end; { TForm1 } procedure TForm1.Button1Click(Sender: TObject); var Units: TUnits; A, B, C: TUnitStyle; begin Units := TUnits.Create; try A := usM3; B := usKNdivM2; C := Units.GetMult(A, B); ShowMessage(Units.AsString[C]); A := usKN; B := usM; C := Units.GetDiv(A, B); ShowMessage(Units.AsString[C]); finally Units.Free; end; end; |
AW: Einheiten parsen
Und warum nicht einen stinknormalen Expression-Parser um Einheiten erweitern und die Umrechnung in die Semantikroutinen legen? Hätte auch noch den Vorteil einer komfortablen Fehlerbehandlung.
|
AW: Einheiten parsen
Wenn du uns noch kurz sagst wo hier eine Exception auftreten kann? :wink:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:07 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