Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Ungewöhnliche ungültige Gleitkommaoperation (https://www.delphipraxis.net/180006-ungewoehnliche-ungueltige-gleitkommaoperation.html)

Mikkey 16. Apr 2014 15:10

Delphi-Version: 7

Ungewöhnliche ungültige Gleitkommaoperation
 
Liste der Anhänge anzeigen (Anzahl: 1)
Vielleicht kann mir ja jemand einen Tipp geben, was hier vorgeht.

Mit dem Einschließen in Try/Except macht das zwar keine Probleme, aber ich wüsste trotzdem gern, wodurch der Fehler verursacht wird und - wenn möglich - wie ich ihn von vornherein vermeiden kann.

Sherlock 16. Apr 2014 15:15

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Hast du mal versucht nur gegen 0 zu vergleichen, also ohne das ".0"?

Sherlock

himitsu 16. Apr 2014 15:21

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Was ist nun eigentlich der Fehler?
Oder ist das "Ungewöhnliche ungültige Gleitkommaoperation" die Fehlermeldung?

Und welchen Wert hat das Value und wo kommt der Wert her?

(z.B. mit NaN lässt sich keine Zahl vergleichen)

p80286 16. Apr 2014 15:25

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von himitsu (Beitrag 1255835)
Und was ist nun eigentlich der Fehler?

gerade mal ausprobiert
Delphi-Quellcode:
procedure pp(t:tdatetime);
begin
  if t<=0.0 then begin
    t:=t+1;
  end;
end;
kein Fehler, nichts!
(ach ja t=now)

Gruß
K-H

himitsu 16. Apr 2014 15:43

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von p80286 (Beitrag 1255836)
(ach ja t=now)

Solltest du dann nicht besser "-" rechnen, um auch mal bei kleiner 0 vorbei zu kommen? :angel:

Aber so lange in t eine "gültige" Fließkommazahl drin ist, gibt es keine Probleme.
Außer nach einer Weile ein eventuelle "Überlauffehler", aber diese Prüfung ist ja standardmäßig deaktiviert.

Zitat:

kein Fehler, nichts!
"Anwendung hängt", müsste da aber schon kommen. :lol:



Gültig:
- kein NaN, Infinity oder NegInfinity
- keine defekter/ungültiger "Wert" (im Gegensatz, zum z.B. Integer, ergibt, auf binärer Ebene, nicht jede Bitkombination einen gültigen "Wert")
- zwischen -MaxDouble und MaxDouble
- und nahe 0 nicht kleiner als MinDouble (nicht zwischen -MinDouble und MinDouble)

Mikkey 16. Apr 2014 15:54

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von Sherlock (Beitrag 1255833)
Hast du mal versucht nur gegen 0 zu vergleichen, also ohne das ".0"?
Sherlock

habbich, das 0.0 war einer der Vermeidungsversuche

Zitat:

Zitat von himitsu (Beitrag 1255835)
Was ist nun eigentlich der Fehler?
Oder ist das "Ungewöhnliche ungültige Gleitkommaoperation" die Fehlermeldung?
Und welchen Wert hat das Value und wo kommt der Wert her?
(z.B. mit NaN lässt sich keine Zahl vergleichen)

"value" ist 0, auch zu sehen im Tooltip, 0 soll dabei ein nicht-angegebenes Datum darstellen. Der Fehler ist das Auslösen der Exception "ungültige Gleitkommaoperation" an der mit dem Pfeil markierten Stelle.

himitsu 16. Apr 2014 16:14

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Nja, de Debugger zeigt die Werte nicht immer "optimal" an, ganz kleine Zahlen rundet der auch schonmal zu einer "glatten" 0
und vorallem mit "defekten" Werten kommt der nicht unbedingt klar. (wer konnt auch ahnen, daß sowas mal passieren könnte)

Ist das denn wirklich eine 0.000000000000000... ?

Was gibt der Code denn aus, wenn du ihn in deine Funktion einfügst?
Delphi-Quellcode:
var
  X: Int64 absolute Value;
begin
  ShowMessage(IntToHex(X, 16));
(PS: Strg+C funktioniert im Quellcode, in Compiler-/Debuggermeldungen und sogar in den Dialogen/Fehlermeldungen)


Delphi-Quellcode:
var
  T: TDateTime;
begin
  T := 0;
  if T < 0 then ;

  T := NaN; // absichtlich kaputte Zahl (definierter Zustand, welchen auch der Debugger versteht)
  if T < 0 then ;

Mikkey 16. Apr 2014 16:40

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von himitsu (Beitrag 1255843)
Nja, de Debugger zeigt die Werte nicht immer "optimal" an, ganz kleine Zahlen rundet der auch schonmal zu einer "glatten" 0
und vorallem mit "defekten" Werten kommt der nicht unbedingt klar. (wer konnt auch ahnen, daß sowas mal passieren könnte)

Ist das denn wirklich eine 0.000000000000000... ?

Zumindest sieht man im Stack an der Stelle (BP+8) zweimal "00000000"

Zitat:

Zitat von himitsu (Beitrag 1255843)
Was gibt der Code denn aus, wenn du ihn in deine Funktion einfügst?
Delphi-Quellcode:
var
  X: Int64 absolute Value;
begin
  ShowMessage(IntToHex(X, 16));
(PS: Strg+C funktioniert im Quellcode, in Compiler-/Debuggermeldungen und sogar in den Dialogen/Fehlermeldungen)

Der gibt garnichts aus, nur die Exception tritt wieder auf. Allerdings wird die Funktion in der Folge noch mehrfach aufgerufen und dabei erscheinen auch Msg-Boxes mit "0000000000000000" (ohne Exception).

PS: Im Quelltext schon, das übrige geht zumindest in meinem Delphi hier nicht.

himitsu 16. Apr 2014 17:40

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von Mikkey (Beitrag 1255846)
Der gibt garnichts aus, nur die Exception tritt wieder auf.

Das ganze läuft aber nicht in einem Thread? (wegen der MessageBox)

Ansonsten sieht es eher so aus, als wenn da irgendwas anderes total zerschossen wäre und nur hier zufällig erst einen Fehler ausgelöst wird, wenn sich nichtmal die MessageBox zeigt.

Mikkey 17. Apr 2014 08:30

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von himitsu (Beitrag 1255857)
Zitat:

Zitat von Mikkey (Beitrag 1255846)
Der gibt garnichts aus, nur die Exception tritt wieder auf.

Das ganze läuft aber nicht in einem Thread? (wegen der MessageBox)

Ansonsten sieht es eher so aus, als wenn da irgendwas anderes total zerschossen wäre und nur hier zufällig erst einen Fehler ausgelöst wird, wenn sich nichtmal die MessageBox zeigt.

Die Exception fliegt aus dem IntToHex, ich bin mit dem Debugger soweit in den Code hinuntergestiegen, wie noch benannte Calls erkennbar waren.

Heute habe ich nochmal die ursprünglichen Daten angesehen, das Feld enthält tatsächlich 8x00, drei darauf folgende Doubles, die mit NaN initialisiert wurden, 000000000000F8FF.

Das Programm hat zwar parallele Threads, die Daten (zum Zeitpunkt des Fehlers) stammen aus der eigenen Initialisierung, erst später kommen die Daten von einem anderen Prozess (per Pipe) - dann tritt der Fehler aber auch nicht mehr auf. Die Messageboxen werden dann anständig angezeigt.

Wie gesagt, der Try/Except umgeht das Problem vollständig, ich würde nur gern wissen, was denn an der Logik falsch ist. Unmittelbar nach dem Aufruf der Funktion mit diesem Wert, wird sie mit drei anderen Feldern des Records aufgerufen, die exakt gleich ( := 0; ) initialisiert werden. Dabei kommt keine Exception.

Ich habe auch versucht, die Werte mit NaN zu initialisieren und entsprechend abzufragen. Dann tritt die Exception nicht mehr in der Funkion auf, sondern irgendwann später und schlägt mit einer Meldung an der Oberfläche auf :-(

Popov 17. Apr 2014 15:15

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Meines Wissens nach (kann aber auch falsch sein) wählt Delphi für einer Konstante stets den kleinsten benötigten Variablentyp. Bei
Delphi-Quellcode:
if value <= 0.0 then
wäre 0.0 demnach Single, value Double, also 4 Byte gegen 8 Byte. Sollte jetzt nicht das Problem sein, denn Null ist Null, nur stellt sich die Frage ob value bis in den letzten Bit Null ist.

Was den try except Einschluss angeht, so weiß ich nicht ob das nötig ist. Negative Datumswerte wie hier
Delphi-Quellcode:
ShowMessage(DateTimeToStr(-5683.458));
führen nicht zum Fehler. Evtl. wäre IsValidDateTime interessanter als gegen Null zu prüfen. Auf jeden Fall bringt try except an der Stelle wenig.

Mikkey 17. Apr 2014 15:35

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
value ist bis in das letzt Bit 0

Zitat:

Zitat von Popov (Beitrag 1256036)
Auf jeden Fall bringt try except an der Stelle wenig.

Bitte entschuldige, aber was soll mir das jetzt bringen? Warum der Try/Except-Block da steht, habe ich bereits zweimal geschrieben. Ich finde es selbst unlogisch, dass ein Vergleich eines Double mit 0 ungültig sein soll.

Anscheinend gerät die Gleitkommalogik in irgendeinen komischen Zustand, der bei der ersten passenden Gleitkommaoperation in einer Exception mündet. Dieselbe Exception sorgt aber anscheinend für eine Bereinigung des Problems, so dass danach keine weiteren Exceptions fliegen.

Popov 17. Apr 2014 16:11

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von Mikkey (Beitrag 1256039)
Warum der Try/Except-Block da steht, habe ich bereits zweimal geschrieben.

Jep, hab nicht soweit gelesen.

Was passiert eigentlich wenn du das so machst?
Delphi-Quellcode:
var
  d: Double;
begin
  d := 0.0;
  if value <= d then

Dejan Vu 17. Apr 2014 17:35

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Also wenn ich die Zeichenkette 'Double' '=' und '0' sehe, werde ich mistrauisch und krame den ersten Satz heraus, den ich als Programmierer gelernt habe: Vergleiche Gleitkommazahlen nie auf Gleichheit und 0.0 ist nicht 0.0.

Ich denke, dein DateTimeToStr knallt hier, denn 0>0.0 (wissen wir ja, ne ;-) ) und dann wird versucht, daraus einen DateTime zu formatieren und das geht irgendwie in die Hose. Kann mich natürlich auch irren, und der Vergleich knallt.

Ich glaube, auch ein Wert von 0.1 (also irgendwie ein paar Minuten nach Mitternacht um die vorletzte Jahrhundertwende) ist ein legitimer Nix-Datum-Wert. Wieso also nicht einfach das hier versuchen
Delphi-Quellcode:
if value < 0.1 then

Mikkey 18. Apr 2014 15:18

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
@Dejan Vu:

Obwohl ich weiß, dass die Zahlen 0 und 1 exakte Repräsentierungen in jedem Fließkommasystem haben, hatte ich Deinen Vorschlag schon selbst ausprobiert - mit demselben Effekt.

Nochmal: Es ist nicht der DateTimeToStr, der knallt, sondern der Vergleich selbst! In Vorschlag von Himitsu was es der IntToHex.

Da nach dem ersten Knall kein weiterer folgt, vermute ich, dass das Problem nichts mit der Zahlvariablen zu tun hat, sondern mit dem Fließkommasystem selbst.

@Popov:

Kann ich aktuell nicht ausprobieren, erst am Di wieder. Bin aber felsenfest davon überzeugt, dass damit genau dasselbe passiert.

Dejan Vu 18. Apr 2014 15:37

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von Mikkey (Beitrag 1256173)
Nochmal: Es ist nicht der DateTimeToStr, der knallt, sondern der Vergleich selbst! In Vorschlag von Himitsu was es der IntToHex.

Das gips doch nich. Ich hatte gehofft, das Du dich geirrt hast. Mein Weltbild gerät ins Wanken.

Klaus01 18. Apr 2014 15:41

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
.. vielleicht kann man zum Vergleichen auch compareDateTime verwenden.

Grüße
Klaus

himitsu 18. Apr 2014 15:48

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Und das zeigt auch nichts an?
Delphi-Quellcode:
var
  P: PByte;
  i: Integer;
  S: string;
begin
  try
    if value <= 0.0 then
      Result := ''
    else
      try
        Result := DateTimeToStr(value);
      except
        on E: Exception do
          ShowMessage('ungültiges Datum: ' + E.Message);
      end;
  except
    on E: Exception do begin
      P := @value;
      for i := 0 to 7 do
        try
          S := S + IntToHex(P[i], 2);
        except
          S := S + '**';
        end;
      ShowMessage('ungültige Zahl: "' + S + '" - ' + E.Message);
    end;
  end;
end;

Popov 18. Apr 2014 17:14

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
@Mikkey

Kann es sein, dass du irgendwo eine spezielle Compilerdirektive nutzt? Mir fällt auf die Schnelle keine ein die zu der Fehlermeldung führen würde, aber wenn du schreibst, dass der Fehler nur einmal vorkommt, dann muss danach irgendetwas passieren, damit es kein weiteres Mal vorkommt. Vielleicht findet beim ersten Aufruf eine Bereichsprüfung statt, die beim weiteren Mal abgestellt ist.

Ich weiß, das Ganze ist etwas weit hergeholt, aber theoretisch möglich.

Namenloser 18. Apr 2014 17:52

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Ich würde mir mal den Wert von
Delphi-Quellcode:
Get8087CW()
ausgeben lassen. Außerdem, könntest du mal einen Breakpoint auf das
Delphi-Quellcode:
begin
setzen, in die Assembler-Ansicht wechseln und den Assembler-Code kopieren und hier posten? Und außerdem mal in der Assembler-Ansicht noch mal Anweisung für Anweisung durchsteppen und gucken, wo genau er abbricht.

Mikkey 19. Apr 2014 17:13

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
@Klaus, Himitsu, Popov, Namenloser:

Das klingt zumindest nach Wegen aus der Krise ;-), am Dienstag werde ich alle mal durchprobieren.

Was ich auf jeden Fall vermeiden muss, ist, den Fehler einfach nicht aufschlagen zu lassen, denn dann tritt er einfach später an irgendeiner Stelle auf (mit entsprechender Meldung "ungültige Gleitkommaoperation" an der Oberfläche.

Mikkey 22. Apr 2014 07:20

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Liste der Anhänge anzeigen (Anzahl: 2)
Aalso:

Ich habe aufgrund der Tipps einiges durchprobiert: der Code sieht so aus (auskommentierte Varianten wurden entsprechend probiert):

Delphi-Quellcode:
class function TdlgKlimaSetup.DateTimeToEdit(value: TDateTime): String;
var
  P: PByte;    //H
  i: Integer;
  S: string;
  cmp: Double; //P
  w8087: Word; //N
begin
  try
    w8087 := Get8087CW(); //N
    cmp := 0.1;
    //if IsNaN(value) or (CompareDateTime(value, cmp) = LessThanValue) then //K
    if value <= cmp then //P
      result := ''
    else
      result := DateTimeToStr(value);
  except
    on E: Exception do begin //H
      P := @value;
      for i := 0 to 7 do
        try
          S := S + IntToHex(P^, 2);
          Inc(P);
        except
          S := S + '**';
        end;
      ShowMessage(Format('ungültige Zahl: "%s" - %s - CW8087=%x', [S, E.Message, w8087]));//HN
    result := '';
    end;
  end;
end;
@Popov:
Auch der Vergleich mit der Variablen hat denselben Effekt. Die Einstellungen sind diese:
Delphi-Quellcode:
A=8 B=0 C=0  D=1 E=0  F=0 G=1 H=1 I=1 J=0 K=0 L=1 M=0 N=1 O=1 P=1 Q=0 R=0 S=0 T=0 U=0 V=1 W=0 X=1 Y=2 Z=1


@Himitsu:
Der Effekt ist derselbe, die Messagebox hängt als Grafik an

@Klaus:
Auch mit CompareDateTime wird dieselbe Exception ausgelöst.

@Namenloser:
Das ausgelesene Control Word ist $1372 (habe ich in der Messagebox mit ausgegeben).
Der Assembercode ist als Grafik wiedergegeben (copy/Paste klappt aus dem CPU-Fenster nicht). Ein Einzelschritt über den FLD von der markierten Stelle führt bereits nach "ntdll.KiUserExceptionDispatcher".

Beim Schreiben ist mir noch eine weitere Idee gekommen:
An den Anfang des Codes habe ich folgendes eingefügt:
Delphi-Quellcode:
    cmp := 0.1;
    Try
    if cmp < 0 then
      cmp := 0.2;
    except
      ShowMessage('Totaler Unsinn');
    end;
Damit erscheint diese Message-Box, aber der übrige Code läuft dann ohne Exception durch. :roll:
Jetzt hoffe ich noch, dass das CW etwas Hilfreiches aussagt.

Mikkey 22. Apr 2014 07:55

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Vielen Dank für die Unterstützung.

Zwar weiß ich immer noch nicht, warum der Fehler sich auf diese Weise bemerkbar macht, aber ich habe den Auslöser gefunden.
Zunächst hatte ich mit einer Codezeile, die den Fehler provoziert, die Stelle gesucht, die den Zustand herbeiführt.
Hier wurde eine mit NaN initialisierte Variable mit =0 verglichen.
Nachdem die Variable zuätzlich gegen NaN verglichen wird, tritt der nachfolgende Fehler nicht mehr auf.

Keine Ahnung, warum nicht bereits beim ersten Vergleich eine Exception fliegt, in der Hilfe steht lediglich:

Zitat:

Verwenden Sie NaN nicht in Vergleichsoperationen

Klaus01 22. Apr 2014 07:59

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
.. es tut mit leid, aber der code wirft keine Exception..

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  value: TDateTime;
  cmp: double;
  w8087: word;
begin
  try
    w8087 := get8087cw;
    value := strToFloat(Edit1.Text);
    cmp := 0.1;
    if value <= cmp then
      edit2.Text := 'less than 0.1 or equal to 0.1'
    else
      edit2.Text := DateTimeToStr(value);
  except
    on E:Exception do
      showMessage(E.Message);
  end;
end;
aber wenn Du schon den Übeltäter gefunden hast..

Grüße
Klaus

Mikkey 22. Apr 2014 08:22

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Der müsste auch eher so ausschauen:

Delphi-Quellcode:
var
  value: TDateTime;
  cmp: double;
  w8087: word;
begin
  try
    cmp := NaN;
    if cmp = 0 then cmp := 0;
    cmp := 0.1;
    value := 0;
    if value <= cmp then // hier müsste die Exception fliegen
      edit2.Text := 'less than 0.1 or equal to 0.1'
    else
      edit2.Text := DateTimeToStr(value);
  except
    on E:Exception do
      showMessage(E.Message);
  end;
end;

Sherlock 22. Apr 2014 08:32

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Ich würde gerne meinen Senf dazu geben, trotzdem oder weil die Sache aufgelöst wurde.
Ich vergleiche seit vielen Jahren Datumsfelder, bzw. prüfe, ob ein DateTime gefüllt/gesetzt ist. Noch nie ist mir sowas passiert. Vermutlich liegt es an meiner Unkenntnis von NaN (Ignorance is bliss). Ein DateTime behandle ich immer als DateTime. Einzig eine gelegentliche Abfrage auf
Delphi-Quellcode:
>0
zum prüfen, ob das Ding gefüllt ist (bei mir gibts Gottlob keine Ereignisse vor 1900) erlaube ich mir, und bin noch nie in ein derartiges Problem gelaufen. Mir ist ehrlich gesagt immer noch unklar, was bei Dir eigentlich warum falsch gelaufen ist. Die Geschichte mit dem NaN würde aber an oberster Stelle auf der kurzen Liste der Verdächtigen stehen...wegen KISS und so ;)

Sherlock

Mikkey 22. Apr 2014 09:36

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
@ Sherlock:
Was würdest Du dann für eine Repräsentation von "nicht vorhanden" in einem Double-Wert verwenden, der als gültiger Wert beispielsweise zwischen -1E6 und 1E6 liegen kann. Früher wurde in dem System so etwas wie 1E32 dafür verwendet, was sich aber als besch^^^^^ungünstig herausgestellt hat.

Sherlock 22. Apr 2014 09:45

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Wie gesagt, ich bin in der glücklichen Situation kein Datum vor 1900 berücksichtigen zu müssen. Ich weiss ja nicht, was Du für eine Anwendung damit betreiben musst, aber bist Du sicher, daß das für Dich nicht gilt?

Sherlock

Mikkey 22. Apr 2014 10:24

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
@ Sherlock:
Zitat:

Zitat von Mikkey (Beitrag 1256450)
Was würdest Du dann für eine Repräsentation von "nicht vorhanden" in einem Double-Wert verwenden, ...

Es geht nicht um das Date/Time-Feld, das könnte ich sogar als ungültig betrachten, wenn es unter 41000 liegt.
Der Fehler entsteht durch Vergleich eines Double (enthaltend NAN) mit 0.

Medium 22. Apr 2014 14:59

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Wenn mich nicht alles täuscht, werden bei Operationen mit NaNs (ja, Mehrzahl. Es gibt viele verschiedenen NaNs, die teils auch unterschiedliche Dinge besagen) in der FPU Flags verwendet, die ansonsten nicht mitspielen. Eventuell ist hier bei deinem Vergleich vorher ein solches gesetzt worden, da man aber dokumentiert hat, dass Vergleichen mit NaN böse ist, wird ggf. nicht mehr weiter auf diese geprüft. Bei nachfolgenden FP Operationen könnte dieses Flag dann zum Knall führen.
Wenn das so zutrifft (ich kann es im Moment nicht wirklich testen), dann finde ich einen kleinen Hinweis in der Doku für zu wenig. Da sollte dann eigentlich auch der Compiler mit einer Meldung kommen, wenn das Kompilat den Fall nicht anderweitig sauber behandelt.

Popov 24. Apr 2014 00:35

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Übrigens, ich hatte heute die Fehlermeldung "Ungültige Gleitkommaoperation" bei dieser Berechnung:
Delphi-Quellcode:
x := Round(637 - 3.6854775808e-4927);
Rauskopiert und einzeln berechnet ergibt das dagegen keinen Fehler.

Medium 24. Apr 2014 01:54

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Jede Wette, dass dabei das selbe raus kommt wie bei
Delphi-Quellcode:
x := 637;
, selbst ohne das Round().

4927 lässt sich kaum in den 11 Bits des Exponenten eines Doubles darstellen, womit deine Zahl dort effektiv 0 ist. Der Exponent geht bei Double von -308 bis +308, ein Bruchteil deines. Demnach sollte dort eine denormalisierte Gleitkommazahl vorliegen, welche durchaus auch schon mal komische Dinge in der FPU tun. Je nach dem was um diese Berechnung herum ähnliches passiert ist, kann das durchaus schon sein.

Edit: Für einen Extended geht das, aber IMHO gibt es die doch auf 64 Bit CPUs gar nicht mehr. Was ist da los?

Amateurprofi 24. Apr 2014 02:12

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von Medium (Beitrag 1256722)
Edit: Für einen Extended geht das, aber IMHO gibt es die doch auf 64 Bit CPUs gar nicht mehr. Was ist da los?

Klar geht das.
Nur wird, wenn deine Zielplattform 64 Bit ist, das Extended Format nicht mehr unterstützt, bei 32 Bit sehr wohl.

Dejan Vu 24. Apr 2014 07:45

AW: Ungewöhnliche ungültige Gleitkommaoperation
 
Zitat:

Zitat von Mikkey (Beitrag 1256450)
@ Sherlock:
Was würdest Du dann für eine Repräsentation von "nicht vorhanden" in einem Double-Wert verwenden, der als gültiger Wert beispielsweise zwischen -1E6 und 1E6 liegen kann. Früher wurde in dem System so etwas wie 1E32 dafür verwendet, was sich aber als besch^^^^^ungünstig herausgestellt hat.

Interpretation oder Kodierung allgemein (1E32 ist 'nicht vorhanden') zur Darstellung von Eigenschaften ist immer Murks. Immer. Du könntest dann auch '1234567' nehmen. Genauso blöd.

Ich würde mit Variants arbeiten. Dort kannst Du wunderbar mit dem als Zahl oder Datum nicht existierenden Wert 'nicht vorhanden' arbeiten, ohne irgendwelche Werte zu interpretieren. Variants haben explizite Konstanten (eigentlich sind das Funktionen, aber wie nicht veränderbare Konstanten zu behandeln), die da heißen 'Unassigned' und 'Null'. Damit hast Du deinen 'nicht vorhanden' Wert explizit dargestellt, kannst vor dem Zugriff prüfen etc.

Wenn Dir Variants nicht passen (es soll Leute geben, die rümpfen die Nase, weil Variants angeblich ultralangsam sind. Oder old school), dann verwende doch einen Record, so in etwa.
Delphi-Quellcode:
Type
  TDateTimeRec = Record
  private
    var
      fValue : TDateTime;
      fIsValid : Boolean;
    function GetValue: TDateTime;
    procedure SetValue(const Value: TDateTime);
  public
    Property Value : TDateTime Read GetValue Write SetValue;
    Property IsValid : Boolean Read fIsValid Write fIsValid;
  End;

{ TDateTimeRec }

function TDateTimeRec.GetValue: TDateTime;
begin
  if not isValid Then Raise Exception.Create('Datetime not valid');
  result := fValue;
end;

procedure TDateTimeRec.SetValue(const Value: TDateTime);
begin
 fValue := Value;
 IsValid := True;
end;
Allerdings sind Variants auch nichts anderes als Records...

Und: Ja, man muss ab und zu ein wenig mehr tippen, wenn man es richtig(er) machen will.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:42 Uhr.

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