Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: scales of justice am 30. May 2006, 19:48
-
ich weis ich hab das vor einiger Zeit schonmal geragt, aber ich probiers jetzt in der Honung, dass es nun jemand weis nochmal:
mein OS ist aus Assembler und C, ür C benutz ich Turbo C,
bis jetzt geht es in meinem OS hauptsächlich darum zu rechnen,
ich hatte immer wieder Probleme mit dem Koprozessor, aber irgendwann hats dann geklappt
eigentlich unktioniert alles ganz gut, nur Sinus und Cosinus wollen einach nicht
ich benutz daür einach die Standardlibs von Turbo C (hab aber auch schon die von Watcom ausprobiert)
dummerweise kommt immer ein alsches Ergebnis raus und ich verstehe einach nicht warum
wenn ich eine ganz normale DOS Anwengung mit Turbo C mache, klappt es, deswegen denke ich, ich initialsiere den Koprozessor nicht richtig
ich initialisiere den einach einmal am anang mit init
muss man das vielleicht öter machen? oder anders?
die Taste zwischen D und G ist aus meiner Tastatur kaputt
deswegen hab ich so ne schöne Rechtschreibung ;-)
(die o.g. Anweisung zum initialisieren hat den Buchstaben übrigens am Anang, also init mit dem Buchstaben davor
-
Na ja, im Extremfall per Taylor-Reihe selbst berechnen. ;)))
-
Wenn du nicht auf alte CPUs festgelegt bist, könntest du auch die SSE-Einheiten zum Rechnen verwenden (oder 3Dnow!...).
Soweit mir das bekannt ist, empfiehlt Intel sowieso die FPU nicht mehr zu verwenden... :roll:
-
das mit der Taylorreihe war ne gute Idee!
hab ne gute Taylorreihe für Sinus gefunden und dann Cosinus aus Sinus berechnet,
aber lieber wärs mir auch direkt eine für Cosinus zu haben, ich weis aber nicht wie sowas geht
kennt vielleicht jemand eine?
oder kann mir aus dieser für Sinus eine für Cosinus machen:
double sinus(double x)
{
return(x * (1 - x * x / 6 * (1 - x * x / 20 * (1 - x * x / 42 * (1 - x * x / 72 * (1 - x * x / 110 * (1 - x * x / 156 * (1 - x * x / 210 * (1 - x * x / 272)))))))));
}
Cosinus mach ich im Moment noch so, falls es jemand braucht:
double cosinus(double x)
{
return(sinus(1.5707963267948966192313216916398 - x));
}
-
bei sinus is ne klammer zuviel^^
-
wo denn?
-
http://de.wikipedia.org/wiki/Cosinus#Definition_als_Taylorreihe
-
hab ich auch schon gefunden, aber so versteh ich das nicht,
ich bräucht das als fertige Gleichung
-
Tjo, da haben wir beide was gemeinsam: Keine Lust.
-
Jetz sach blos du kanst mit der formel für cos(x) nix anfangen?
cos(x) = die summe aller n von 0 bis in alle weigkeit
(-1 hoch n) * (x hoch (2*n) ) / ( 2*n)!
für n = 0, 1, 2, 3, 4, .... berechnest du das ergebnis der angegebenen formel. und summierst sie auf.
(-1 hoch n) sollte ja kein problem sein oder doch?
(x hoch (2*n)) sollte jetzt auch nicht die wellt sein oder etwa doch? für n = 0 (achtung ausnahme ist das ergebnis) 1 für n = 1 gibt das x*x für n =2 kommt x*x*x*x raus.
( 2*n)! gibt zu wenn man nicht weiss was es ist hat man ein problem. a! ist nichts anderes als das Produckt aller zahlen von 1 bis a bedeutet somit das für n = 0 (achtung ausnahme) 1 rauskommt, für n = 1 => 2 für...
n = 0 > -1^0 * x*(0) / (0)! => 1 * 1 / 1
n = 1 > -1^1 * x*(2) / (2)! => -1 * (x*x) / (1*2)
n = 2 > -1^2 * x*(4) / (4)! => -1 * -1 * (x*x*x*x) / (1*2*3*4)
n = 3 > -1^3 * x*(6) / (6)! => -1 * * (x*x*x*x*x*x) / (1*2*3*4*5*6)
n = 4 > -1^4 * x*(8 ) / (8 )! => 1 * (x*x*x*x*x*x*x*x) / (1*2*3*4*5*6*7*8 )
und über die einzelnen ergebnisse bildest du jetzt die summe.
lässt sich wunderschön in ner schleife machen, und wenn in einem schritt das zwischenergebniss so klein ist das es an der von dir vorgegebenen genauikeit keine veränderung ergibt, kannst du abbrechen ;)
Der grund dafür ist, das x^n für x zwischen 0 und 1 maximal zwischen 0 und 1 schwanken kann. n! wird für n gegen sehr gross immer grösser. da x^n durch n! diviediert wird ergibt sich ein sehr kleiner wert bzw für das nächste n ein kleinerer als der vorherige ( ohne vorzeichenbetrachtung )
gruss
[edit] vermaledeite 8) grr [\edig]
-
Tjo, da haben wir beide was gemeinsam: Keine Lust.
Lust hab ich schon, aber keine Ahnung, wie man das in eine einfache Gleichung umwandeln soll
@Termite:
ich blick gar nix mehr, was ist überhaupt n?
das mit sinus hab ich von der Seite:
http://home.in.tum.de/~prilmeie/tgi/maschinen/entwicklerdokumentation.html
da steht dass die Gleichung (nicht die obere, unten is noch eine) im Hornerschema ist und deswegen besser sein soll
weis vielleicht jemand wie man das Gleiche, also im Hornerschema irgendwie für Cosinus machen kann?
-
Hi
n ist eine variable für die die nacheinander die Natürlichen Zahlen 0, 1, 2, 3, 4, ( wir können das bis an unser lebensende weiter machen,....) einsetzt.
n = 0;
while(1 == 1 )
{
n = n+1;
}
somit definiert man in der matematik schleifen ( so in etwa )
die beiden sinus formeln sind gleich sie haben nur eine andere darstellung. Du kanst die eine in die andere überführen. Mit der Unteren, mit der nach horna, kann man genauer rechnen, da dort nur ein x^2 vorkommt in den anderen bis zu x^9, Dadurch ergeben sich entweder sehr grosse bzw sehr kleine ergebisse dafür. Durch die interne darstellung im rechner als float ergibt sich dann ein problem beim addieren solcher zahlen.
das kann z.B. der grund sein, wenn man 1.000.000.000 mal 1/1.000.000.000 zu 1.000.000.000 dazuadiert nicht 2.000.000.000 sondern nur 1.000.000.000 herauskommt. ( additions / subtraktionskatastrophe ) Programmtechnisch in einer schleiffe mit adition gelöst, nicht mit multiplikation!
Der vorteil beim Hornaschema ist der, das es keine Summenbildung ist, sondern ein Produckt. Dadurch werden, grosse und kleine zahlen miteinander multipliziert, was zu weniger rundungsfehlern führt.
Horna sollte im zusammenhang mit Paralben und Polinomen ein begriff sein. damit kann man richtig lustige sachen machen, nicht nur funktionswerte berechnen, Sondern auch funktionswerte der ableitungen ohne diese zu haben ;) Ableiten geht auch, ( wenn man eine nullstelle hat )
Aber ich lass das mal lieber. Hier fehlt scheintsich einiges an mathematischem grundlagenwissen.
gruss
-
na dann muss mein Mathelehrer mir die Formel wohl sagen...
-
Horna sollte im zusammenhang mit Paralben und Polinomen ein begriff sein. damit kann man richtig lustige sachen machen, nicht nur funktionswerte berechnen, Sondern auch funktionswerte der ableitungen ohne diese zu haben ;) Ableiten geht auch, ( wenn man eine nullstelle hat )
Aber ich lass das mal lieber. Hier fehlt scheintsich einiges an mathematischem grundlagenwissen.
Und bei dir fehlt wohl Grundlagenwissen der Rechtschreibung... :lol:
Parabeln, Polynome und Horner-Schema...
Schöne Endlosschleife übrigens...
n = 0;
while(1 == 1 )
{
n = n+1;
}
Warum nicht so? *gg*
for(int n = 0;;n++);
-
Ist doch auch egal. Aber eine Taylorreihe geht für exakte Werte nun mal bis unendlich. Aber auch nach ner Weile sind die Werte zumindestens gut.
Ich hab in meinem Analysisbuch vom 1. Semester allgemein die Formel für ne Taylorreihe drin, aber ehrlich gesagt, wenn du Probleme mit der Formel für cos(x) bei Wikipedia hast wird dir die noch nicht viel Freude machen. ;)
-
Hi zusammen.
@ C#ris: warum nicht gleich so:
int i = 0;
for(;;) {
i++;
}
Ergiebt auch ne Endlosschleife
-
Hi zusammen.
@ C#ris: warum nicht gleich so:
int i = 0;
for(;;) {
i++;
}
Ergiebt auch ne Endlosschleife
Das ist doch das gleiche :wink:
-
Hi
for (int i = 0; ; i++)
{
}
wird kein c compiler übersetzen. int i wird inerhalb der for schleife deklariert und das ist in c nicht zulässig! Variablen müssen am anfang eines Blocks vor der ersten anweisung / zuweisung deklariert werden.
gruss
-
Tjo, mit C++ geht das. ;)
-
Ihr koenntet euch die Taylor-Reihen einfach selbst herleiten. Abgesehen davon brauchst du den Sinus sowieso nur fuer 2pi Periodenlaenge (Einheitskreis), und davon eigentlich auch nur die Haelfte. D.h. du suchst oder berechnest dir eine Taylor-Reihe, die fuer den ersten Gupf vom Sinus genau ist, nimmst die halbe Periode, setzt sie hinten negativ drauf und fertig...das ganze kannst du bis in alle Ewigkeit machen, weil der Sinus gleich bleibt. Fuer den Cosinus kannst du den ganzen Schmafoo nochmal machen, oder du berechnest dir den Sinus mit Phasenverschiebung pi/2. ;)
Mich wuerde hingegen interessieren wie das in glibc und diversen anderen C runtime libs implementiert ist..wisst ihr da was?
Lg, Alex
-
Also ich würde meinen das hängt mit dem jeweiligen Compiler zusammen der eine akzeptiert es und der andere wiederum nicht und nach Syntaxt ist das so wie Termite geschreiben hat, bin mir dessen nicht sicher, nehme es aber an.
Freundliche Grüsse
Neo3
-
Also ich würde meinen das hängt mit dem jeweiligen Compiler zusammen der eine akzeptiert es und der andere wiederum nicht und nach Syntaxt ist das so wie Termite geschreiben hat, bin mir dessen nicht sicher, nehme es aber an.
Klar, das hängt ab ob es als C oder C++ Code kompiliert wird und von nix anderem ;) Voraussgesetzt die Compiler halten sich an die Standards.
for(int i = 0;;i++);
wird in keinen C Compiler funktionieren, wie Termite schon richtig gesagt hat.
Vielleicht sollte man den Offtopic-Blödsinn, den ich da angestoßen habe lassen... :wink:
-
Ihr koenntet euch die Taylor-Reihen einfach selbst herleiten
glaubst du echt, das hätte ich nicht gemacht, wenn ichs könnte?
genau das ist ja das Problem
meine Sinus-Taylorreihe ist auch nur von - 2Pi (- 360°) bis 2Pi (360°), die hab ich aber auch nur hinbekommen, weil ich einfach eine andere abgeschrieben und weitergeführt hab
-
seht mal was ich in der Turbo C Anleitung gefunden hab:
Q. Why do I get incorrect results from all the math library
functions like cos() and tan()?
A. You must #include <math.h> before you call any of the standard
Turbo C math functions. In general, Turbo C assumes that a function
that is not declared returns an int. In the case of math functions,
they usually return a double. For example
/* WRONG */ /* RIGHT */
#include <math.h>
main() main()
{ {
printf("%f", cos(0)); printf("%f", cos(0));
} }
-
oder kann mir aus dieser für Sinus eine für Cosinus machen:
double sinus(double x)
{
return(x * (1 - x * x / 6 * (1 - x * x / 20 * (1 - x * x / 42 * (1 - x * x / 72 * (1 - x * x / 110 * (1 - x * x / 156 * (1 - x * x / 210 * (1 - x * x / 272)))))))));
}
Da sin(X)^2 + cos(x)^2 = 1 ist, kann man einfach folgendes machen:
double cosinus(double x)
{
return(1-pow(sinus(x),2))
}
-
less erst mal alles, bevor du postest
so eine zwischen Lösung hab ich schon,
deine ist nur noch schlechter, da ich erst noch pow implementieren müsste
ich such eine eigenständige Taylorreihe für Cosinus, nicht die 100. Umrechnung von sinus
-
ich denk du hast dein fehler mit dem include schon gefunden?
aber wenn es dich wirklich interesiert gibt es hir mal die formel
double sin(double x) {
double x2 = x*x;
return x * (1-x2/(2*3) * (1-x2/(4*5) * (1-x2/(6*7) * (1-x2/(8*9) * ... ;
}
double sin(double x) {
double x2 = x*x;
return 1-x2/(1*2) * (1-x2/(3*4) * (1-x2/(5*6) * (1-x2/(7*8) * ... ;
}
ich glaub mit 7 gliedern war man schon genau genug für den bereich von 2pi um null. achja, das fehlt übrigens noch, die begrenzung auch den bereich in der die funktionen ausreichend genau arbeiten.
x = x - round(x/(2*PI))*2*PI;
so oder so ähnlich müsste es funktionieren. bersönlich find ich es ziehmlich blödsinnig da ihr hier flieskommazahlenen (double) mit hilfe der fpu berechnen lasst, und dann nicht auf die sinus bzw. cosinus funktionen der fpu zurückgreift.
@Azi:
es fehlt noch das wurzelziehn