Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Problem mit SIN (X), Vorzeichen Changen


h4nnes_ - Do 15.02.07 18:15
Titel: Problem mit SIN (X), Vorzeichen Changen
Hi Leutz!

Ich habe ein Problem mit meinem Programm!

Formel: SIN(X)=x- x^n/n! + x^n/n! - x^n/n! + - + ...

das ganze dann so zB.

Benutzer gibt für x:2 und für n:7 ein:

SIN(X)=2-2^3/3! + 2^5/5! - 2^7/7!


kapiert das irgendwer von euch?

was ich bis jetzt habe:

funktion für die Fakultät, Kontrollstruktur!, Nicht viel!!!

Bitte nun um Hilfe um ein paar Tipps, vor allem wie ich das Vorzeichen zwischen + und - die ganze Zeit ändere!

Ich hoffe ihr versteht das... es ist eine HÜ, und ich seh schwarz... :(

MFG johannes!


Allesquarks - Do 15.02.07 19:20

Ich würde das da oben umschreiben denn es ist missverständlich bis falsch.

Das ist die Taylorreihen also entweder Summe über n [(-1)^n*x^n/n!] oder halt x-x^3/3!+x^5/5!

Aber nun zu deinem Problem:
Du kannst das Vorzeichen wechseln mit einer Multiplikation mit -1 das ist aber ganz schöne verschwendung.

Ansonsten für integers:

Delphi-Quelltext
1:
2:
3:
4:
5:
function changesign(int integer):integer;
asm
   not eax;
   inc eax;
end;


oder für Gleitkommazahlen:

Delphi-Quelltext
1:
2:
3:
4:
5:
function changesign(myfloat:extended):extended;
asm 
   fld myfloat;
   fchs;
end;


Wens erstmal nur ums hinbekommen geht dann ists ok ansonsten kann ich dir nur sagen es ist eine unglaubliche Verschwendung von Rechenzeit jedesmal Fakultät oder so aufzurufen.


Spaceguide - Di 27.02.07 23:33

Verschwendung von Rechenzeit ist wohl eher der Funktionsaufruf ;-)


Horst_H - Mi 28.02.07 14:44

Hallo,

die Taylor-Reihe von sin(x) läßt sich ja durch ausklammern umschreiben, wenn du ein festes n(= Anzahl der vorgegeben Summenglieder) hast.
Du kannst dann ala Hornerschema rechnen.
sin(x) = x*(1/1 - x°2/(2*3)*(1-x^2/(4*5)*(1-x^2/(6*7)*(1-x^2...-x^2/((2*n-2))*(2*n-1)){n-fach}))
Du berechnest also x^2 und dann rückwärts


Delphi-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:
procedure TForm1.Button1Click(Sender: TObject);
var
  x2,
  x,
  sinx : double;
  i,n,n2_1:integer;
begin
n := 7;
x := 1;
x2 := x*x;
n2_1 := n+n-1;
sinX := 1;
For i := n downto 2 do
  begin
  sinX := 1-x2/((n2_1-1)*n2_1)*sinX;
  n2_1 := n2_1-2;
  Memo1.Lines.Add(Format(' %0.9f',[sinX]));
  end;
//den Rest mal x
sinX := x*sinX;

Memo1.Lines.Add(Format(' %0.9f',[sinx]));
Memo1.Lines.Add('');
Memo1.Lines.Add(Format(' %0.9f',[sin(x)]));
end;



Gruß Horst


Spaceguide - Do 01.03.07 10:50

Die Reihe sollte man eh rückwärts berechnen, wegen der begrenzten Genauigkeit von Gleitkommavariablen. Immer zuerst die kleinen Werte aufsummieren.