Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Die Sache mit der Null (https://www.delphipraxis.net/180167-die-sache-mit-der-null.html)

Popov 27. Apr 2014 16:18


Die Sache mit der Null
 
Ich weiß, ich sehe evtl. vor lauter Bäume nur den Wald nicht mehr, aber ich sehe den Fehler nicht.

Das ist ein Auszug aus einer Routine, auf das Nötigste gekürzt. j ist Null, c wird aus x + j berechnet, a nur aus x. Da j Null ist, sollten die Werte gleich sein.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
const
  x = 6000000;
var
  a, b, c, j: Extended;
begin
  j := 0;

  ShowMessage('x hat den Wert = ' + FloatToStr(x));
  ShowMessage('j hat den Wert = ' + FloatToStr(j));
  c := Sqr(x + j);
  ShowMessage('Quadrat c hat den Wert = ' + FloatToStr(c));
  a := Sqr(x);
  ShowMessage('Quadrat a hat den Wert = ' + FloatToStr(a));
  b := c - a;
  ShowMessage('c - a hat den Wert = ' + FloatToStrF(b, ffNumber, 15, 2));
end;
Also ich weiß nicht ob auf anderen Rechner das auch vorkommt, aber c und a sind bei mit unterschiedlich.


//Edit:

Ok, gelegentlich muss man einen Beitrag schreiben, damit der Groschen fällt. Delphi nimmt für die Konstanten immer die kleinste nötige Variable, so dass es x evtl. als Integer betrachtet.
Delphi-Quellcode:
const
  x: Extended = 6000000;
Damit wird die Berechnung korrekt ausgeführt.

Trotzdem, der Unterschied ist gewaltig. Ob ich ein Integer potenziere oder Real, das Ergebnis sollte ja gleich sein, wenn der Empfänger Real ist.

Union 27. Apr 2014 16:28

AW: Die Sache mit der Null
 
Nein, sollte es nicht. Extended sind "ungenau". Deshalb vergleicht man die z.B. auch mit CompareValue. Warum das so ist kannst Du hier sehen.

Popov 27. Apr 2014 16:33

AW: Die Sache mit der Null
 
Das mag stimmen, aber der Unterschied ist bei c - a = 35.996.120.907.776,00. Mag sein, dass das stimmt was du geschrieben hast, aber ich denke das Problem lag ausnahmsweise hier an anderer Stelle.

Mathematiker 27. Apr 2014 17:01

AW: Die Sache mit der Null
 
Hallo,
ich habe einmal getestet, in welcher Form Delphi
Delphi-Quellcode:
const x = 6000000;
interpretiert.
Dein merkwürdiges Ergebnis entsteht, wenn x als longword erkannt wird. Bei integer oder int64 kommt auch etwas Falsches heraus (Differenz = 36.000.415.875.072,00).
Ich finde es erstaunlich, dass die Konstante derart verarbeitet wird. Ein Warnhinweis des Compilers wäre wohl angebracht.

Beste Grüße
Mathematiker

BUG 27. Apr 2014 18:14

AW: Die Sache mit der Null
 
Zitat:

Zitat von Popov (Beitrag 1257174)
Ob ich ein Integer potenziere oder Real, das Ergebnis sollte ja gleich sein, wenn der Empfänger Real ist.

Eben nicht :wink:
Bei der Auswahl der passenden Überladung einer Funktion wird der Typ des Rückgabewerts nicht berücksichtigt, aber der Typ der Argumente.
Deswegen kannst du auch nicht mehrere Überladungen einer Funktion haben, die sich nur im Rückgabewert unterscheiden.

Uwe Raabe 28. Apr 2014 07:13

AW: Die Sache mit der Null
 
Zitat:

Zitat von Mathematiker (Beitrag 1257178)
Ein Warnhinweis des Compilers wäre wohl angebracht.

Bzw. eine Exception zur Laufzeit bei eingeschaltetem Overflow-Checking! Möchte dazu jemand einen QC anlegen?

Zur Lösung reicht übrigens auch ein simpler Punkt:

Delphi-Quellcode:
const
  x = 6000000.;

himitsu 28. Apr 2014 08:08

AW: Die Sache mit der Null
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1257211)
Zur Lösung reicht übrigens auch ein simpler Punkt:

Meinst du nicht eher ein simples
Delphi-Quellcode:
.0
?

So wäre es ja ein ungültiges Zahlenformat. :gruebel:

DeddyH 28. Apr 2014 08:11

AW: Die Sache mit der Null
 
Mein XE akzeptiert auch den Punkt ohne Nachkommastellen anstandslos, das habe ich bislang auch noch nicht gewusst.

Popov 28. Apr 2014 09:33

AW: Die Sache mit der Null
 
Zitat:

Zitat von himitsu (Beitrag 1257215)
Zitat:

Zitat von Uwe Raabe (Beitrag 1257211)
Zur Lösung reicht übrigens auch ein simpler Punkt:

Meinst du nicht eher ein simples
Delphi-Quellcode:
.0
?

Die Umwandlung eines Integers mittels Multiplikation mit Real, wie z. B.
Delphi-Quellcode:
ShowMessage(Format('%.0n', [1000 * 1.0]));
ist ja ein altbekannter Trick. Das Problem war, dass bei der Potenzierung von 6.000.000 das Ergebnis um 36.000.415.875.072 danebenlag, weil er die 6000000 als Integer potenziert hat und nicht als Real. Wenn man weiß was das Problem ist, gibt es 1001 Lösungen dafür 8-)

Zitat:

Zitat von DeddyH (Beitrag 1257216)
Mein XE akzeptiert auch den Punkt ohne Nachkommastellen anstandslos, das habe ich bislang auch noch nicht gewusst.

Akzeptiert Delphi 7 auch.

Mikkey 28. Apr 2014 10:40

AW: Die Sache mit der Null
 
Zitat:

Zitat von Popov (Beitrag 1257223)
Zitat:

Zitat von DeddyH (Beitrag 1257216)
Mein XE akzeptiert auch den Punkt ohne Nachkommastellen anstandslos, das habe ich bislang auch noch nicht gewusst.

Akzeptiert Delphi 7 auch.

Sollten aber beide nicht tun.

Schaut man mal die Pascal-Syntaxdiagramme für "konstante Zahl ohne Vorzeichen" an, muss auf einen Dezimalpunkt zwingend eine weitere Ziffer folgen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:08 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