Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > C/C++
You last visited: Today at 22:58

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Phytagoras ohne math.h

Discussion on Phytagoras ohne math.h within the C/C++ forum part of the Coders Den category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Jun 2011
Posts: 265
Received Thanks: 50
Phytagoras ohne math.h

Hey Leute,

Ich hab mich nochmal an meinen "mini Rechner" gesetzt und festgestellt dass unter anderem die Phytagoras-Berechnung fehlt. Wollte das ganze ohne den math.h machen.

Schaut daweil so aus:

PHP Code:
case '5'//Phytagoras c^2 = a^2 * b^2
            
const double j 0.00000000001;
            
double i
            
buffer = ( zahl1 zahl1 ) * ( zahl2 zahl2 );
            
std::cout << "Ergebnis: c^2 = " << buffer << std::endl;
            for( 
0.00000000001!= buffer; )
            {
                
i;
            }
            
erg i;
            
std::cout << "Ergebnis: c = " << erg << std::endl;
            break; 
Da diese Methode aber zu viel Zeit und Performance in anspruch nimmt, möchte ich fragen ob wer eine andere Idee hat.

Mfg,
Kosic
Kosic is offline  
Old 01/08/2013, 10:09   #2
 
elite*gold: 5
Join Date: Sep 2006
Posts: 385
Received Thanks: 218
Naja, du könntest inline ASM nutzen und das Zeug somit berechnen.

Code:
int main()
{
	auto a = 2 * 2;
	auto b = 3 * 3;
	auto c = a * b;
	double c_root = 0.0f;

	__asm
	{
		fild c;
		fsqrt;
		fst c_root;
	}
}
Ist jedoch ziemlich unflexibel und lässt sich nur mit vergleichbar viel Aufwand erweitern. Abgesehen davon ist das der totale Overkill! Was spricht gegen math.h?
Nightblizard is offline  
Old 01/08/2013, 10:12   #3
 
xNopex's Avatar
 
elite*gold: 0
Join Date: May 2009
Posts: 827
Received Thanks: 471
Ich würde vorschlagen, du verwendest das Heron - Verfahren. Ich habe das gerade mal getestet mit 10 Iterationsschritten. Funktioniert sehr schön.
xNopex is offline  
Thanks
1 User
Old 01/08/2013, 15:53   #4


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
Ansonsten gibt es für sin, cos, sqrt und Konsorten afaik auch gute Näherungspolynome. Muss es denn so dermaßen exakt sein, dass du in deiner Schleife so kleinschrittig vorgehst? Nicht umsonst rechnen Physiker nicht genauer, als sie messen können
MrSm!th is offline  
Old 01/08/2013, 21:28   #5
 
xNopex's Avatar
 
elite*gold: 0
Join Date: May 2009
Posts: 827
Received Thanks: 471
Näherungspolynome sind eher ungeeignet. Man entwickelt hier um einen bestimmten Punkt und erhält dann für genau diesen Punkt genaue Ersatzpolynome. Werte, die weiter weg von diesem Punkt liegen kriegen einen mehr oder weniger großen Fehler mit. Das hängt zum einem vom Grad des Ersatzpolynoms ab zum anderen kommts auch wirklich drauf an, wie weit weg man vom Entwicklungspunkt ist. Iterationsverfahren sind hier weitaus komfortabler.
Bei Sinus (und cos dann auch) verhält sich das nochmal anders. Hier herrscht eine engere Verbindung zur e-Funktion, sprich man kann einen sinus 1:1 in eine Kombination aus e-Funktionen übersetzen. Zum programmieren hilft das allerdings auch nicht wirklich weiter.
Ich werbe an dieser Stelle nochmal für das Heronverfahren ;O
xNopex is offline  
Thanks
2 Users
Old 01/08/2013, 23:07   #6
 
elite*gold: 0
Join Date: May 2010
Posts: 793
Received Thanks: 268
würde dir auch Heronverfahren nahelegen
nkkk is offline  
Thanks
1 User
Old 01/09/2013, 06:24   #7
 
elite*gold: 0
Join Date: Jun 2011
Posts: 265
Received Thanks: 50
Wenn ichs richtig verstanden habe, müsste es doch so aussehen, oder?( Der erste Näherungsversuch) den Zweiten probiere ich heute Nachmittag.

Code:
        buffer = ( zahl1 * zahl1 ) * ( zahl2 * zahl2 );
	std::cout << "Ergebnis: c^2 = " << buffer << std::endl;
			
	buffer2 = ( buffer + 1 ) / 2;
	buffer3 = buffer / buffer2;
	buffer4 = ( buffer2 + buffer3 ) / 2;


	erg = buffer4;
	std::cout << "Ergebnis: c = " << erg << std::endl;
Kosic is offline  
Old 01/09/2013, 09:42   #8

 
snow's Avatar
 
elite*gold: 724
Join Date: Mar 2011
Posts: 10,479
Received Thanks: 3,318
Machs doch mit Rekursion? Da ist das Heron-Verfahren doch ideal dafür..

x(n + 1) = (x(n) + a / x(n)) / 2 -> x(n) = (x(n - 1) + a / x(n - 1)) / 2

Als Code:

Code:
double x(n, a)
{
    double y = (n == 0) ? a : x(n - 1, a);
    return (y + a / y) / 2;
}
(das war jetzt nur kurz aus dem Kopf raus, kann man garantiert noch optimieren)

Falls du nicht weißt, wie du das verwenden sollst: erg = x(5, buffer); -> weniger als 5 liefert ein falsches Ergebnis.

Gib Bescheid, ob es klappt.

(bestimmt ist das jetzt komplett falsch und voll peinlich. )
snow is offline  
Old 01/09/2013, 13:50   #9
 
elite*gold: 0
Join Date: Jun 2011
Posts: 265
Received Thanks: 50
Verstehe deinen Code nicht, snow.

Sorry :S
Kosic is offline  
Old 01/09/2013, 14:06   #10

 
snow's Avatar
 
elite*gold: 724
Join Date: Mar 2011
Posts: 10,479
Received Thanks: 3,318
Ist dir die Rekursion bekannt? Wenn nein, solltest du es evtl. so machen, wie du es bisher gemacht hast.

Code:
double x(n, a)
{
   double y = 0;

   if (n == 0) // für x(0) kann man a nehmen, statt x(n) + a / x(n) können wir hier also a + a / x einsetzen
       y = a; 
   else 
       y = x(n - 1, a); // y ist das Ergebnis von x(n -1)
return (y + a / y) / 2; // y in die Formel einsetzen
}
Schwierig zu verstehen, das stimmt. :/

Über eine Iteration ist es evtl. einfacher:

Code:
double wurzel = 0;

for (int i = 0; i < MAX_DURCHLAUF; i++) {

if (i == 0) // wenn es der erste Durchlauf, also x(0) ist
 wurzel =  (buffer + 1) / 2;
else 
 wurzel = (wurzel + buffer / wurzel) / 2; // x(nächstes) = (x(aktuelles) + a / x(aktuelles)) / 2

}

printf("Die Wurzel von c beträgt %lf", wurzel);
Keine Ahnung, ob das klappt, hocke hier gerade in der Vorlesung.
snow is offline  
Thanks
1 User
Old 01/09/2013, 14:36   #11
 
elite*gold: 0
Join Date: Jun 2011
Posts: 265
Received Thanks: 50
Habs jetz so gemacht: (Problem solved)

Code:
case '5': //Phytagoras c^2 = a^2 * b^2
		float c2;
		float x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10;
		c2 = ( zahl1 * zahl1 ) * ( zahl2 * zahl2 );
		std::cout << "Ergebnis: c^2 = " << c2 << std::endl;
		
		x0 = ( c2 + 1 ) / 2;

		x1 = ( x0 + ( c2 / x0 ) ) / 2;

		x2 = ( x1 + ( c2 / x1 ) ) / 2;

		x3 = ( x2 + ( c2 / x2 ) ) / 2;

		x4 = ( x3 + ( c2 / x3 ) ) / 2;

		x5 = ( x4 + ( c2 / x4 ) ) / 2;

		x6 = ( x5 + ( c2 / x5 ) ) / 2;

		x7 = ( x6 + ( c2 / x6 ) ) / 2;

		x8 = ( x7 + ( c2 / x7 ) ) / 2;

		x9 = ( x8 + ( c2 / x8 ) ) / 2;

		x10 = ( x9 + ( c2 / x9 ) ) / 2;

		erg = x10;
		std::cout << "Ergebnis: c = " << erg << std::endl;
		break;
Kosic is offline  
Old 01/13/2013, 13:56   #12
 
elite*gold: 0
Join Date: Sep 2010
Posts: 10,215
Received Thanks: 5,781
Quote:
Originally Posted by xNopex View Post
Näherungspolynome sind eher ungeeignet. Man entwickelt hier um einen bestimmten Punkt und erhält dann für genau diesen Punkt genaue Ersatzpolynome. Werte, die weiter weg von diesem Punkt liegen kriegen einen mehr oder weniger großen Fehler mit. Das hängt zum einem vom Grad des Ersatzpolynoms ab zum anderen kommts auch wirklich drauf an, wie weit weg man vom Entwicklungspunkt ist. Iterationsverfahren sind hier weitaus komfortabler.
Bei Sinus (und cos dann auch) verhält sich das nochmal anders. Hier herrscht eine engere Verbindung zur e-Funktion, sprich man kann einen sinus 1:1 in eine Kombination aus e-Funktionen übersetzen. Zum programmieren hilft das allerdings auch nicht wirklich weiter.
Ich werbe an dieser Stelle nochmal für das Heronverfahren ;O
e-Funktion, trigonometrische Funktionen etc. werden vom Taschenrechner und PC alle über Taylor-Reihen berechnet. Die Wurzel kann man dann über diese grundlegenden Funktionen annähern.

sqrt(x) = exp(1/2* ln(x)) = (exp(ln(x)))^(1/2) = sqrt(exp(ln(x))) = sqrt(x)

Zumindest glaube ich, dass das so gehandhabt wird. Nicht, dass ich sonst alle Mathe-Vorlesungen verschlafen würde :-p
theitfan1337 is offline  
Old 01/13/2013, 14:26   #13
 
xNopex's Avatar
 
elite*gold: 0
Join Date: May 2009
Posts: 827
Received Thanks: 471
Bei Sinus und Co kann ich mir noch vorstellen, dass mit Taylorpolynomen das ganze ausgerechnet wird. Hier genügt es ja eine Periode anzunähern. Werte größer 2pi oder kleiner 0 kann man dann immer auf diese Periode abbilden.
Bei "komplexeren" Funktionen bin ich mir nicht ganz sicher. Die zu verwendenden Taylopolynome müssten hier schon von höherer Ordnung sein, um genaue Ergebnisse zu bekommen. Das Heron-Verfahren wäre im Beispiel der Wurzelfunktion imho einfacher und genauer. Aber ich kenne das Problem mit dem Verschlafen..
xNopex is offline  
Old 01/13/2013, 14:39   #14
 
elite*gold: 0
Join Date: Sep 2010
Posts: 10,215
Received Thanks: 5,781
Kommt drauf an was du mit komplexeren Funktionen meinst. Im Prinzip ist es doch meistens möglich, eine Funktion durch sin, cos, exp oder log anzunähern. Zu denen kennt man die passenden Reihen-Entwicklungen und somit kann man dann alles in vergleichsweise wenig Iterationsschritten recht genau berechnen.
Wobei mir das Heron-Verfahren eig ganz gut gefällt. Nur gibt es eben nicht immer für jede komplexe Funktion eine so "einfache" Iterationsvorschrift.
theitfan1337 is offline  
Old 01/13/2013, 20:19   #15
 
xNopex's Avatar
 
elite*gold: 0
Join Date: May 2009
Posts: 827
Received Thanks: 471
Naja im Gegensatz zu sin, cos, etc. die periodisch sind und man deshalb nur eine Periode annähern muss, muss man bei ln, e, etc. über den gesamten Definitionsbereich annähern. Und als Nutzer möchte ich dann natürlich genauso genaue ergebnisse für extrem kleine Werte, wie für extrem große Werte erhalten. Sprich mein Taylorpolynom müsste von höherer Ordnung als die gewohnten ersten zwei Glieder sein, die man so immer mal schriftlich ausrechnet. Ergebnisse auf 9Stellen genau sind meistens genug. Das schafft auch mein Taschenrechner. Jetzt müsste man eben ausrechnen, bis zur welchen Ordnung man entwickeln muss. Mein Gefühl sagt mir, dass das nicht wenig sein wird.
Den Aufwand könnte man sich eben durch z.b. ein Heron Verfahren sparen.
xNopex is offline  
Reply


Similar Threads Similar Threads
[Quest]math.cos und math.sin
08/22/2010 - Metin2 Private Server - 10 Replies
Hallo, anscheinend kennt Metin2 die Funktionen math.cos und math.sin nicht, gibt es trotzdem eine Möglichkeit die irgendwie zu benutzen? (Für den DT ;))
iSRO Math
08/03/2009 - Silkroad Online - 30 Replies
Close
Math/var help
07/02/2009 - CO2 Private Server - 1 Replies
Ok simplifying this post alot. How do I transfer things already loaded into the source from a database into the useitem area? Maybe I'm over complicating things but I am not able to do it.. In my Database.cs I have Struct.SPoints Port = new Struct.SPoints(); loading in things from the database. I need a way to apply those values to a similar code in UseItem.cs where I have my public static void ScrollPointTele(int PointId, int MapEnd, int PointX, int PointY, ClientSocket CSocket)
Any good at math
12/11/2006 - Eudemons Online - 3 Replies
Ok I posted a mesage earlier saying im wanting to hack this game. If you want email me for the VB code and i will send you a sample program (not compiled so its 100% virus free) to help you adjust game values. My program will be more usefull however when I find the real address for the character position. Now in replies to my earlier posts some dummy tried saying rotate 45 degrees bla bla bla. I've tried this and still havent got it right. Besides if you notice as you walk around there are no...



All times are GMT +1. The time now is 23:00.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.