PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Falsche Ergebnisse bei sqr() und sqrt()


Poison Nuke
21.09.2002, 17:15
Hallo,

ich habe mal wieder ein Problem :(

Ich will Berechnungen mit Vektoren durchführen (Abstandsberechnung usw.) aber bei der Brechnung der Länge eines Vektors kommen falsche Werte heraus, obwohl ich diesmal wohl fast alles ausprobiert habe.


Hier der Code der Berechnung:


CONST cube : array[1..8,1..3] of integer =
(( 150,-150,-150),( 150, 150,-150),
(-150, 150,-150),(-150,-150,-150),
( 150,-150, 150),( 150, 150, 150),
(-150, 150, 150),(-150,-150, 150));
TYPE vektor = array[1..3] of integer;
VAR point : vektor;
x1,x2,x3 : longint;
tiefe : real;
cam : vektor;
i,j : byte;
BEGIN
cam[1]:=500; cam[2]:=0; cam[3]:=0;
FOR i:=1 TO 8 DO BEGIN
FOR j:=1 TO 3 DO point[j]:=cube[i,j];
x1:=sqr(cam[1]-point[1]);
x2:=sqr(cam[2]-point[2]);
x3:=sqr(cam[3]-point[3]);
tiefe:=sqrt(x1+x2+x3);
END;
END;


Beim ersten Durchlauf sollte für x1 122500 rauskommen, aber es kommt -8742 raus und für "tiefe" sollte 410 rauskommen, es kommt aber 190 raus.

Ich habe schon zwei andere Programmierer per ICQ gefragt, aber auch sie wussten nicht, wieso falsche Werte herauskommen.
Ich hoffe ihr könnt mir erklären, woran das liegt.


Diogenes
21.09.2002, 17:28
Kann ich:

Du hast wohl den Range-Check abgeschaltet:{$R-}In dem Fall wird nicht auf Überlauf geprüft und du bekommst keineFehlermeldung, Integers speichern in so einem Fall nur die untersten 16 Bits und damit eben nicht alles.

Gegenvorschlag: Nimm statt Integer LongInt oder Real.

Alle Klarheiten beseitigt?

Poison Nuke
21.09.2002, 17:37
Die entsprechenden Werte sind ja schon als Longint oder Real deklariert. Deswegen kommt es mir ja grade so komisch vor.

Und auch mit eingeschaltetem Rangecheck wird es falsch berechnet.

Diogenes
21.09.2002, 18:05
Ich sehe da aber alles (direkt oder indirekt) als Integer deklariert... :confused:

Ich meine: Wenn Du das in deine Arrays umspeicherst, wird ins Integer-Format umgewandelt. Dann kannst Du diese Fehler bekommen. :mauer:

Poison Nuke
21.09.2002, 18:11
Original geschrieben von Poison Nuke

VAR point : vektor;
x1,x2,x3 : longint;
tiefe : real;
cam : vektor;
i,j : byte;


Diese beiden (markierten) Variablen sind aber als Longint bzw als Real deklariert und auch nur diese sind meiner Meinung nach für die Ergebnisse zuständig. Die Vektoren selbst habe ich nur als Integer deklariert, aber sie müssen ja auch nur Werte -1000<x<1000 aufnehmen.

Diogenes
21.09.2002, 18:17
In


x1:=sqr(cam[1]-point[1]);
x2:=sqr(cam[2]-point[2]);
x3:=sqr(cam[3]-point[3]);


sind cam[ i ] und point[ i ] Integers. Das Argument ist also selbst vom Integer-Typ und deshalb auch das Ergebnis von sqr ("Integer rein - Integer raus"). Hier dürfte der Fehler entstehen. Du könntest z.B. mit

x1:=sqr(Real(cam[1])-Real(point[1]));

arbeiten (sog. Typecasting) oder meinen Vorschlag von oben annehmen.

Poison Nuke
21.09.2002, 18:26
Vielen Dank.

Jetzt geht es.

Das wusste ich noch gar nicht, das man bei solchen Rechenoperationen auf die Typen der Varablen in der Gleichung achten muss. :mauer: :mauer: