Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Sinus Wert ungenau!
BiG-BennY - Sa 28.02.09 22:49
Titel: Sinus Wert ungenau!
Hallo Freunde,
ich hab endlich meinen Rechner fertiggestellt und bin auch ziemlich glücklich damit.
Leider habe ich ein Problem, anstatt das bei Sinus 90 der Wert 1 rauskommt, kommt 0,9999999958 oder so rauß!
Was könnte das Problem sein?
Weitere Nullen bei der Wurzelberechnung sind nicht möglich, da sonst die Wurzel zu lange berechnet.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TGrundflaeche.SinusClick(Sender: TObject); var b,s,z,w : Extended ; const pi=3.1415926535897932384626433832795; begin
Zahl1 := StrToFloat(Anzeigefeld1W.Caption);
b := ( Zahl1 / 1048576 ); s := ((b*pi)/180); z := 20;
WHILE z<>0 DO
begin z := z-1; w := (1-(s*s)); w := WurzelFunktion(w,2); s := (2*s*w); end;
Ergebnisausgabe.Caption := FloatToStr(s);
end; |
und die dazugehörige Funktion :
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
| function Pot(b,e:Single):Single; var v:Single; begin
IF e=0 THEN Pot := 1 ELSE begin v:=1;
WHILE e > 0 DO
begin v:=v*b; e:=e-1; end; // While Anweisungsblock
Pot := v; end; // IF Anweisungsblock
end;
function WurzelFunktion(r:Extended;n:Cardinal):Extended; var unten,mitte,oben:Extended; begin
IF r >= 1 THEN begin unten:=1; oben:=r; end ELSE begin unten:=r; oben:=1; end;
WHILE (( oben - unten ) > 0.0000000001 ) DO
begin mitte := ((unten+oben)/2); IF Pot(mitte,n) > r THEN oben:=mitte ELSE unten:=mitte; end;
WurzelFunktion := ((unten+oben)/2)
end; |
mfG
Benny
Hidden - Sa 28.02.09 23:04
Hi :wave:
Das liegt an der Genauigkeit das Datentyps, würde ich mal sagen. Extended hat zwar sehr viele Nachkommastellen, aber du hast 20 Durchläufe, bei denen diese Ungenauigkeit quadratisch einfließt(w := 1 - (s*s)).
Ich nehme mal an, es handelt sich um ein Projekt? Ansonsten wären natürlich die vordefinierten, tabellenbasierten Funktionen genauer und schneller.
mfG,
Sirke - Sa 28.02.09 23:16
Ich kenne diese Näherung der Sinusfunktion nicht, jedoch eine andere die - wenn ich mich recht erinnere - auch ziemlich genau war!
Quelltext
1: 2: 3: 4: 5: 6: 7:
| sin = 0 j = inputnumber
for i = 1 to 500 do sin = sin + j j = -j * x^2 / ( (2i + 1) * 2i ) end |
... und es verzichtet auf die Wurzel ;-)
Reinhard Kern - Sa 28.02.09 23:26
BiG-BennY hat folgendes geschrieben : |
Hallo Freunde,
ich hab endlich meinen Rechner fertiggestellt und bin auch ziemlich glücklich damit.
Leider habe ich ein Problem, anstatt das bei Sinus 90 der Wert 1 rauskommt, kommt 0,9999999958 oder so rauß!
Was könnte das Problem sein?
Weitere Nullen bei der Wurzelberechnung sind nicht möglich, da sonst die Wurzel zu lange berechnet.
...
|
Hallo,
deine Funktion Pot ist Single - das ist jetzt zwar keine qualifizierte Fehlerfortpflanzungsrechnung, aber grundsätzlich kannst du so nicht erwarten, dass dein Ergebnis besser ist als Single (so etwa ist es ja auch). Du musst schon alles mit der geforderten Genauigkeit rechnen.
Gruss Reinhard
BiG-BennY - So 01.03.09 00:42
So,
kleines Update -> Ich habs jetzt hinbekommen indem ich alles auf Extended umgestellt hab
und dann noch mit ffNumber die Nachkommastellen auf 9 begrenzt hab ^^ ( kleines Workaround ;) )
Funktioniert jetzt auch alles so, wie ich es geplant hatte :)
Danke für eure Hilfe!
Ich denke wenn ich es so am Dienstag meiner Lehrerin vorzeige wird sie zufrieden sein.
( Deswegen kommt auch leider kein anderer Algorithmus in Frage )
mfG
Benny
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!