AGB  ·  Datenschutz  ·  Impressum  







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

floating point invalid operation: 10.1 vs. 10.2

Ein Thema von striderx · begonnen am 28. Mär 2018 · letzter Beitrag vom 29. Mär 2018
Antwort Antwort
Seite 1 von 2  1 2      
striderx

Registriert seit: 11. Feb 2007
Ort: Bergisch Gladbach
206 Beiträge
 
Delphi 10.4 Sydney
 
#1

floating point invalid operation: 10.1 vs. 10.2

  Alt 28. Mär 2018, 17:09
Delphi-Version: 10.2 Tokyo
Der nachstehende Code läuft unter Delphi 10.1 ohne Problem, bei Delphi 10.2 kommt eine Exception (floating point invalid operation). Plattform ist jeweils Windows 32 Bit.

Delphi-Quellcode:
procedure TdlgMain.Test3;

var
  AWord: Word;
  ADouble: Double;

begin
  AWord := 64536;
  ADouble := SQRT(SQR(AWord) + SQR(AWord));
end;
???

Da ich den Source-Code von 10.1 nicht habe (Starter), kann ich nicht nachsehen, ob sich da etwas getan hat.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: floating point invalid operation: 10.1 vs. 10.2

  Alt 28. Mär 2018, 17:47
Die Hilfe zu SQR() sagt:
Zitat:
Der Rückgabewert (das Quadrat) hat denselben Typ wie X und ist mit der Anweisung X*X identisch.
Das Quadrat passt aber nicht mehr in ein Word und erzeugt so einen internen Überlauf, der in einer negativen Zahl resultiert. Durch die Addition bleibt die Zahl negativ und das SQRT kracht natürlich.

Bei 10.1 gibt es da zwar keine Exception, aber das Ergebnis stimmt leider auch nicht: 64.536² + 64.536² = 8.329.790.592

Delphi-Quellcode:
var
  AWord: Word;
begin
  AWord := 64536;
  Writeln(SQR(AWord) + SQR(AWord)); // => 33920
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
striderx

Registriert seit: 11. Feb 2007
Ort: Bergisch Gladbach
206 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: floating point invalid operation: 10.1 vs. 10.2

  Alt 28. Mär 2018, 18:25
Hallo Uwe,

danke für die Erläuterung - das hatte ich mir schon gedacht.

Die Frage ist nur: Wie bekomme ich es vorerst hin, dass auch unter 10.2 keine Exception kommt? Und was hat sich denn zwischen 10.1 und 10.2 geändert?


Der Hintergund: Ich nutze das als eine Art Zufalls-Generator für einen Graphik-Effekt, den ich zufällig entdeckt habe. Das hat natürlich mit sauberer Programmierung überhaupt nichts zu tun, aber ich habe das bislang noch nicht anderweitig nachbauen können.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#4

AW: floating point invalid operation: 10.1 vs. 10.2

  Alt 28. Mär 2018, 18:31
Statt Word Cardinal nehmen oder einen Typen, der in der Lage ist, das Ergebnis aufzunehmen?

Oder ganz grausilig:
Delphi-Quellcode:
procedure TdlgMain.Test3;

var
  AWord: Word;
  ADouble: Double;
  ATemp: Double;

begin
  AWord := 64536;
  ATemp := SQR(AWord + 0.0); // Das Quadrat muss man nicht zweimal berechnen
                             // und + 0.0 macht aus dem Word 'nen Fließkommawert.
  ADouble := SQRT(ATemp + ATemp);
end;
  Mit Zitat antworten Zitat
striderx

Registriert seit: 11. Feb 2007
Ort: Bergisch Gladbach
206 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: floating point invalid operation: 10.1 vs. 10.2

  Alt 28. Mär 2018, 18:57
So kommt keine Exception, aber der Wert von ADouble ist natürlich anders und der Effekt klappt nicht.

Um den Effekt nachzubauen, müsste ich verstehen, was genau passiert, wenn bei 10.1 keine Exception kommt - das tue ich derzeit noch nicht. Es kommen aber immer die selben 'falschen'/'richtigen' Werte raus.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#6

AW: floating point invalid operation: 10.1 vs. 10.2

  Alt 28. Mär 2018, 19:17
Dann berechne doch das Ergebnis einmal "zu Fuß" und vergleiche es mit dem Ergebnis ohne Exception. Stimmen die überein?

Wenn es so ist, wie Uwe es beschrieb, ist das Berechnungsergebnis, bei der Variante ohne Exception, schlicht und einfach falsch.

Oder anders:
Delphi-Quellcode:
var
  AWord: Word;
  AWord2: Word;
  ACardinal: Cardinal;
  ADouble1: Double;
  ADouble2: Double;
  ADouble3: Double;

begin
  AWord := 64536;
  ACardinal := 64536;
  ADouble1 := 64536;
  AWord := SQR(AWord);
  ACardinal := SQR(ACardinal);
  ADouble1 := SQR(ADouble1);

  ADouble1 := SQRT(ADouble1 + ADouble1);
  ADouble2 := SQRT(AWord + AWord);
  ADouble3 := SQRT(ACardinal + ACardinal);
  MessageDlg(Format('1. %f%s2. %f%s3.%f', ADouble1,#13,ADouble2,#13,ADouble3]),mtInformation,[mbOk],0);
end;
Wenn ich da jetzt nicht zuviele Schreib- und Denkfehler drinne haben sollte, so wären drei identische Ergebnisse identischer Berechnungen mit unterschiedlichen Datentypen zu erwarten.

Frage: Ist dem (bei der Variante ohne Exception) so?
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#7

AW: floating point invalid operation: 10.1 vs. 10.2

  Alt 28. Mär 2018, 20:18
So kommt keine Exception, aber der Wert von ADouble ist natürlich anders und der Effekt klappt nicht.
Warum willst Du denn unbedingt den Effekt haben? Wenn Du den Soureccode ändern kannst, dann mach es doch gleich richtig: Erst die Zuweisung an die Double-Variable und die dann quadrieren. Aller andere ist buggy. (Was passiert eigentlich, wenn Du Overflow/Range-Check eingeschaltet hast?)
  Mit Zitat antworten Zitat
striderx

Registriert seit: 11. Feb 2007
Ort: Bergisch Gladbach
206 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: floating point invalid operation: 10.1 vs. 10.2

  Alt 28. Mär 2018, 23:44
@Delphi.Narium

Danke für deine Mühe, aber das ist es leider noch nicht. Zwar bekomme ich bei dem nachstehenden Code keinen Floating Point Fehler mehr, dafür jetzt einen Integer-Überlauf.

Delphi-Quellcode:
var
  AWord: Word;
  ADouble: Double;
  ACardinal: Cardinal;

begin
  AWord := 64536;
  ACardinal := SQR(AWord);
  ADouble := SQRT(ACardinal + ACardinal);
end;
Unter 10.1 enthält ADouble den 184,17. Mathematisch korrekt wäre natürlich 91267,69


@gammatester
Warum ich den Effekt haben will? Weil man damit tolle Bilder erstellen kann. Die von dir vorgeschlagene Vorgehensweise bringt auch nicht das gewünschte Ergebnis. Das alles ist übrigens unabhängig davon, ob die Bereichs-Prüfung an oder ausgeschaltet ist.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: floating point invalid operation: 10.1 vs. 10.2

  Alt 29. Mär 2018, 00:07
Delphi-Quellcode:
AWord := 64536;
ADouble1 := Sqrt(Cardinal(Sqr(Word(AWord))) * 2);
ADouble2 := Sqrt(Cardinal(Sqr(Integer(AWord))) * 2);
ADouble3 := Sqrt(Cardinal(Sqr(Cardinal(AWord))) * 2);
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: floating point invalid operation: 10.1 vs. 10.2

  Alt 29. Mär 2018, 00:11
Zwar bekomme ich bei dem nachstehenden Code keinen Floating Point Fehler mehr, dafür jetzt einen Integer-Überlauf.
Ich denke, du solltest AWord zu einem Cardinal machen. Das Quadrat eines Word passt immer in einen Cardinal, aber halt nicht immer in einen Integer oder gar ein Word. Da der Rückgabewert von SQR den gleichen Typ hat wie das Argument, muss das Argument schon ein Cardinal sein, bei dem das Hi-Word gleich 0 ist. Andernfalls bekommt man einen Integeroverflow.

Am sichersten fährst du, wenn AWord gleich als Double oder Extended deklariert wird.

Delphi-Quellcode:
var
  AWord: Double;
  ADouble: Double;

begin
  AWord := 64536;
  ADouble := SQRT(SQR(AWord) + SQR(AWord));
end;
Du kannst es dem Compiler aber auch leichter machen und es gleich so schreiben:

Delphi-Quellcode:
  AWord := 64536;
  ADouble := SQRT(2)*AWord;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  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 09:23 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