AGB  ·  Datenschutz  ·  Impressum  







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

Case-Statement für Float-Werte

Ein Thema von Andreas L. · begonnen am 15. Jun 2020 · letzter Beitrag vom 17. Jun 2020
Antwort Antwort
Seite 1 von 2  1 2      
Andreas L.

Registriert seit: 23. Mai 2011
Ort: Furth im Wald
308 Beiträge
 
Delphi 11 Alexandria
 
#1

Case-Statement für Float-Werte

  Alt 15. Jun 2020, 10:01
Delphi-Version: 10.3 Rio
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;
Andreas Lauß
Blog
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.222 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Case-Statement für Float-Werte

  Alt 15. Jun 2020, 10:06
Was spricht dagegen das du nur mit ganzen Prozentwerten arbeitest.
Damit hast du einen Integer und kannst wieder mit case-Statement arbeiten.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman
Online

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.431 Beiträge
 
Delphi 12 Athens
 
#3

AW: Case-Statement für Float-Werte

  Alt 15. Jun 2020, 10:06
Moin...
Zitat:
Wie kann ich das Problem lösen?
...den Eingangswert x 100 vor dem case.
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.811 Beiträge
 
Delphi 12 Athens
 
#4

AW: Case-Statement für Float-Werte

  Alt 15. Jun 2020, 10:17
Moin...
Zitat:
Wie kann ich das Problem lösen?
...den Eingangswert x 100 vor dem case.
Trunc nicht vergessen, oder round, oder was auch immer genutzt wird, um ein Integer zu erhalten.

Gleitkommazahlen sind nun mal mathematisch keine Ordinalen.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Case-Statement für Float-Werte

  Alt 15. Jun 2020, 10:24
Dazu lässt sich 0.10 auch gar nicht exakt als Single darstellen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.116 Beiträge
 
Delphi 2009 Professional
 
#6

AW: Case-Statement für Float-Werte

  Alt 15. Jun 2020, 10:25
Dazu lässt sich 0.10 auch gar nicht exakt als Single darstellen.
Oder überhaupt als Kommazahl mit Exponenten-Basis 2.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.168 Beiträge
 
Delphi 12 Athens
 
#7

AW: Case-Statement für Float-Werte

  Alt 16. Jun 2020, 14:02
Moin...
Zitat:
Wie kann ich das Problem lösen?
...den Eingangswert x 100 vor dem case.
Das sehe ich auch als Lösung an, also konkreter mal so in der Art:
Delphi-Quellcode:
function TfrmEditor.GetZoomFactorAsPercent(
  AZoomFactor: Single = 1): TibZoomFactorPercent;
begin
  Result := TibZoomFactorPercent.Custom;
  case Trunc(AZoomFactor * 100) of // Hier tritt der Fehler auf...
      10: Result := TibZoomFactorPercent.Percent10;
      25: Result := TibZoomFactorPercent.Percent25;
      50: Result := TibZoomFactorPercent.Percent50;
      75: Result := TibZoomFactorPercent.Percent75;
    100: Result := TibZoomFactorPercent.Percent100;
    125: Result := TibZoomFactorPercent.Percent125;
    150: Result := TibZoomFactorPercent.Percent150;
    175: Result := TibZoomFactorPercent.Percent175;
    200: Result := TibZoomFactorPercent.Percent200;
    250: Result := TibZoomFactorPercent.Percent250;
    300: Result := TibZoomFactorPercent.Percent300;
    400: Result := TibZoomFactorPercent.Percent400;
    500: Result := TibZoomFactorPercent.Percent500;
  end;
Alles mit "Wert = 0.10" KANN nicht funktionieren, also genausowenig mit case,
weil man float Werte nicht einfach vergleichen kann.
(Siehe unten die Vorschläge mit SameValue)
Deshalb wird es ein case mit float nicht geben können.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#8

AW: Case-Statement für Float-Werte

  Alt 17. Jun 2020, 00:08
Um den Grund an sich noch mal auf den Punkt zu bringen:

CASE und IF sind nur funktional miteinander verwandt. CASE war ursprünglich mehr als nur eine andere (kürzere) Schreibart für eine Kette von IF-Statements, da es dem Compiler hier einfacher war effizienteren Maschinencode daraus zu generieren. Einschränkung: Da dafür Sprungtabellen (bestehend aus relativen Adressen, die halt immer ganzzahlig sind) aus den zu unterscheidenden Werten gebildet wurden/werden, waren/sind nur solche als Kriterium zulässig. In Zeiten, in denen jeder einzelne Prozessorzylus noch in vielfachen (Dollar-)Cents zu bemessen war, war das eine lukrative Angelegenheit.
Und auch heute noch sind solche "kleinkarierten" Optimierungen hier und da noch messbare Vorteile - jedoch werden diese immer seltener, und das Argument der einfacheren Schreib-/Lesbarkeit ist in den Vordergrund gerückt. Welcher Seite man als Compiler-Hersteller nun die Stange hält, ist meiner Meinung nach weitestgehend Geschmackssache. Delphi hat die Optimierbarkeit beibehalten, und somit die Beschränkung auf Ordinaltypen. Will man das nicht, muss man mit diesem Compiler etwas tricksen um die Lesbarkeit zu erhalten, oder einen anderen wählen und die Optimierbarkeit aufgeben.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.342 Beiträge
 
Delphi 12 Athens
 
#9

AW: Case-Statement für Float-Werte

  Alt 17. Jun 2020, 01:43
Es gäbe aber keinen Grund Beides nicht zu kombinieren.

Wenn der CASE-Wert Ordinal ist, dann den optimierten Code generieren,
und ansonsten könnte der Compilier das notfalls auch als viele IF-ElseIf-ElseIf-...-Else umsetzen,
bzw. für Strings in ein CASE mit IndexStr/IndexText übersetzen usw.

Denn wenn wir versuchen das Vorhaben so zu optimieren, damit es ins CASE passt,
dann kommt weniger lesbarer Code bei raus, als wenn das der Compilier intern anpassen würde.


Genauso wie es echt saudoof ist, dass IN immernoch als grauenhaftes SET-Assembler übersetzt wird, anstatt es optional mit BitMasken oder InArray umzusetzen.
Oder dass CharInSet intern nur Mist macht und man den Dreck nicht wieder entfernt, weil IN durch ein IN in einer Funktion zu ersetzen, welche einfach nur die CompilerWarnung unterdrückt, dass ist sowas von schwachsinnig nutzlos.
Wobei das CharInSet-Problem sofort behoben ist, wenn man für "IN WideChar" die grade erwähnte Verbesserung hätte, oder einfach die selbe Codeoptimierug verwenden würde, wie aktuell beim CASE.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (17. Jun 2020 um 01:55 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.168 Beiträge
 
Delphi 12 Athens
 
#10

AW: Case-Statement für Float-Werte

  Alt 17. Jun 2020, 06:35
Und auch heute noch sind solche "kleinkarierten" Optimierungen hier und da noch messbare Vorteile - jedoch werden diese immer seltener, ...
Ich denke CASE hat durchaus seine Berechtigung behalten, wenn mehrere, vieleicht > 3 Fälle bearbeitet werden müssen.
Das sollte immer schneller sein als sequentielles IF.

Falls du Recht hast das dies nicht schneller ist würde es doch bedeuten
das der Compiler das IF intern doch als Sprungtabelle optimiert, oder nicht ?

Schneller wäre vielleicht nur ein Auslagern in Prozeduren-Pointer, als einfache State-Machine
statt CASE oder IF, aber auch das bezweifele ich wenn im case nur wenig gemacht wird.
Da kann der Compiler doch perfekt optimieren (wenn er das könnte).

Die Sprungtebellen der CPU sollten doch das effektivste Mittel bleiben, oder habe ich da was verpasst ?
(Ich habe aber die letzten Jahre intensives CPU-Technologie Studium geschwänzt, Hauptsache das Ding läuft )
  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:30 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