Delphi-PRAXiS
Seite 1 von 3  1 23   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Case-Statement für Float-Werte (https://www.delphipraxis.net/204644-case-statement-fuer-float-werte.html)

Andreas L. 15. Jun 2020 11:01

Delphi-Version: 10.3 Rio

Case-Statement für Float-Werte
 
Hallo,
ich habe gerade ein simples Case-Statement mit Single-Werten geschrieben. Leider kann ich es nicht kompilieren. Die Meldung lautet:
Zitat:

E2001 Ordinaltyp erforderlich
Mir ist klar das ein Single kein Ordinal-Typ ist. Aber es kann doch nicht sein das man kein Case auf Float anwenden kann? Wie kann ich das Problem lösen? Gibt es irgendeine Funktion dafür (wie z.B. CharInSet, etc.), muss das über RTTI gemacht werden oder komme ich um einfache If-Abfragen nicht vorbei?

So habe ich es versucht:
Delphi-Quellcode:
  TibZoomFactorPercent = (
    Custom,
    Percent10,
    Percent25,
    Percent50,
    Percent75,
    Percent100,
    Percent125,
    Percent150,
    Percent175,
    Percent200,
    Percent250,
    Percent300,
    Percent400,
    Percent500
  );

function TfrmEditor.GetZoomFactorAsPercent(
  AZoomFactor: Single = 1): TibZoomFactorPercent;
begin
  Result := TibZoomFactorPercent.Custom;
  case AZoomFactor of // Hier tritt der Fehler auf...
    0.10: Result := TibZoomFactorPercent.Percent10;
    0.25: Result := TibZoomFactorPercent.Percent25;
    0.50: Result := TibZoomFactorPercent.Percent50;
    0.75: Result := TibZoomFactorPercent.Percent75;
    1: Result := TibZoomFactorPercent.Percent100;
    1.25: Result := TibZoomFactorPercent.Percent125;
    1.50: Result := TibZoomFactorPercent.Percent150;
    1.75: Result := TibZoomFactorPercent.Percent175;
    2: Result := TibZoomFactorPercent.Percent200;
    2.50: Result := TibZoomFactorPercent.Percent250;
    3: Result := TibZoomFactorPercent.Percent300;
    4: Result := TibZoomFactorPercent.Percent400;
    5: Result := TibZoomFactorPercent.Percent500;
  end;
end;

Bernhard Geyer 15. Jun 2020 11:06

AW: Case-Statement für Float-Werte
 
Was spricht dagegen das du nur mit ganzen Prozentwerten arbeitest.
Damit hast du einen Integer und kannst wieder mit case-Statement arbeiten.

haentschman 15. Jun 2020 11:06

AW: Case-Statement für Float-Werte
 
Moin...:P
Zitat:

Wie kann ich das Problem lösen?
...den Eingangswert x 100 vor dem case. :wink:

Sherlock 15. Jun 2020 11:17

AW: Case-Statement für Float-Werte
 
Zitat:

Zitat von haentschman (Beitrag 1467299)
Moin...:P
Zitat:

Wie kann ich das Problem lösen?
...den Eingangswert x 100 vor dem case. :wink:

Trunc nicht vergessen, oder round, oder was auch immer genutzt wird, um ein Integer zu erhalten.

Gleitkommazahlen sind nun mal mathematisch keine Ordinalen.

Sherlock

Uwe Raabe 15. Jun 2020 11:24

AW: Case-Statement für Float-Werte
 
Dazu lässt sich 0.10 auch gar nicht exakt als Single darstellen.

Redeemer 15. Jun 2020 11:25

AW: Case-Statement für Float-Werte
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1467301)
Dazu lässt sich 0.10 auch gar nicht exakt als Single darstellen.

Oder überhaupt als Kommazahl mit Exponenten-Basis 2.

stahli 15. Jun 2020 11:26

AW: Case-Statement für Float-Werte
 
Entweder
Delphi-Quellcode:
Round(AZoomFactor * 100)
oder

mehrere if´s in dieser Form:
Delphi-Quellcode:
function TfrmEditor.GetZoomFactorAsPercent(
  AZoomFactor: Single = 1): TibZoomFactorPercent;
begin
  Result := TibZoomFactorPercent.Custom;

  if (AZoomFactor = 0.10) then Exit(TibZoomFactorPercent.Percent10);
  if (AZoomFactor = 0.25) then Exit(TibZoomFactorPercent.Percent25);
...
end;
Im Grunde ist die zweite Variante noch übersichtlicher.
Sie ist etwas aufwendiger zu tippen, aber das ist ja ein einmaliger Aufwand. Man ist auch etwas freier in der Ausgestaltung.

Zu beachten ist, dass Floatwerte immer Ungenauigkeiten beinhalten können.
Deshalb sollte man ggf. eine Funktion wie SameValue zum Vergleich verwenden.

himitsu 15. Jun 2020 11:56

AW: Case-Statement für Float-Werte
 
Und statt
Delphi-Quellcode:
AZoomFactor = 0.10
bei Floats besser mit Delphi-Referenz durchsuchenSameValue rumspielen.

Andreas L. 16. Jun 2020 10:25

AW: Case-Statement für Float-Werte
 
Danke für eure vielen Antworten. Das ich mit ganzen Prozenten oder mit If-Abfragen das Problem lösen kann war mir von Anfang an klar. Ich wollte nur wissen warum es nicht möglich ist Float-Werte in einem Case-Statement zu verwenden. Ebenso Strings. Liegt das "nur" am Daten-Typ oder wurde es einfach nicht im Compiler implementiert? Ich hatte mal einen PreCompiler (ich glaube es war IDE Fix Pack oder so ähnlich) mit dem man u. a. Strings in Case verwenden konnte. Das war vor über 10 Jahren... Warum baut Embarcadero sowas nicht mal ein? Floats, Strings, etc. Ich finde das wäre ein tolles Feature...

stahli 16. Jun 2020 11:01

AW: Case-Statement für Float-Werte
 
Ja, ich fände das auch gut.

Es würde sich ja lediglich um eine andere Schreibweise von if-Statements handeln.
Der Compiler könnte quasi identischen Maschinencode wie bei if-Statements erzeugen.

Schwieriger wäre sicherlich, das auch dem Debugger beizubringen.

Wie hoch der Aufwand letztlich in Summe wäre, kann ich nicht wirklich beurteilen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:43 Uhr.
Seite 1 von 3  1 23   

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