c++ lernen. schleifen? wer kann helfen??

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Sebastian.S
Beiträge: 437
Registriert: 13.04.2003 13:17:41

c++ lernen. schleifen? wer kann helfen??

Beitrag von Sebastian.S » 06.06.2003 18:54:17

Hallo,
ich bin gerade dabei, c++ zu lernen. Meine erste Schleife soll das Heron-Verfahren anwenden, um eine Wurzel zu ziehen. (Heron ist auf: http://home.t-online.de/home/arndt.brue ... frame2.htm dokumentiert)

Meine Schleife sieht so aus:

Code: Alles auswählen

#include <iostream>
using namespace std;

int main() {

double wurzel_aus=2, startwert=2, quadrat=4;
int durchlauf=10, durchlauf2=0;

cout << "Bitte geben Sie die zu radizierende Zahl ein: _" ;
cin >> wurzel_aus;
cout << "\nStartwert? _";
cin >> startwert;


	 while (durchlauf>0) {
	//while (quadrat = wurzel_aus) {
		startwert=((startwert+wurzel_aus/startwert)/2);
		quadrat=startwert*startwert;
		if (quadrat=wurzel_aus) --durchlauf; else durchlauf=durchlauf;
		++durchlauf2;
		// --durchlauf;
	}
cout << "Ergebnis: " << startwert << endl << (startwert*startwert) << endl << durchlauf2 << endl;

}
Das Ergebnis:

Code: Alles auswählen

Bitte geben Sie die zu radizierende Zahl ein: _159753

Startwert? _1
Ergebnis: 404.478
163602
10
Das Programm macht immer nur zehn Durchläufe, obwohl die Wurzel noch nicht vollständig berechnet ist. Warum wird die if-Schleife ausgeführt??

Benutzeravatar
feltel
Webmaster
Beiträge: 10476
Registriert: 20.12.2001 13:08:23
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Leipzig, Germany
Kontaktdaten:

Beitrag von feltel » 06.06.2003 19:22:39

... moved nach "Softwareentwicklung und -paketierung, Scripting"

keyem
Beiträge: 303
Registriert: 23.08.2002 07:50:28
Wohnort: Berlin

Beitrag von keyem » 06.06.2003 19:23:01

Du hast einen typischen C-Fehler in Deinem Programm: in C/C++ wird für den Vergleich der "=="-Operator benutzt, für die Zuweisung das "=".

keyem

Benutzeravatar
Sebastian.S
Beiträge: 437
Registriert: 13.04.2003 13:17:41

Beitrag von Sebastian.S » 06.06.2003 20:06:41

Ups. Wohl ein Anfängerfehler...

Noch eine Frage: Ich habe das Problem jetzt gelöst, aber die Schleifer wird nie verlassen, obwohl das Programm testweise auch bei 65535 Durchläufen die Bedingung Quadrat==wurzel_aus erfüllt hatte. Warum wird die Schleife nicht verlassen?

Schleife wurde angepasst:

Code: Alles auswählen

	while (quadrat!=wurzel_aus) {
		startwert=((startwert+wurzel_aus/startwert)/2);
		quadrat=startwert*startwert;
		//--durchlauf; //if (-1 < quadrat-wurzel_aus < 1) {--durchlauf;}
		 ++durchlauf2;
	}

Benutzeravatar
jogix
Beiträge: 776
Registriert: 05.10.2002 20:08:16
Wohnort: Lampertheim
Kontaktdaten:

Beitrag von jogix » 06.06.2003 20:15:10

Äh?! Du hast aber nicht
if (-1 < quadrat-wurzel_aus < 1)
als Abfrage da stehen oder?! Das geht nämlich nicht!

Ansonsten kann ich Dir nur raten, bei numerischen Problemen die numerischen Ausdrücke nicht mit == bzw. != abzufragen, da oft kleine Ungenauigkeiten von z.B. 1*10^-8 in den ausdrücken zu finden sind und somit == nicht erfüllt wird!
cheers,
Jochen
___________________________________________________
Testing can prove the presence of bugs, but not their absence. -- Dijkstra

Benutzeravatar
Sebastian.S
Beiträge: 437
Registriert: 13.04.2003 13:17:41

Beitrag von Sebastian.S » 06.06.2003 20:52:05

jogix hat geschrieben:Äh?! Du hast aber nicht
if (-1 < quadrat-wurzel_aus < 1)
als Abfrage da stehen oder?! Das geht nämlich nicht!

Ansonsten kann ich Dir nur raten, bei numerischen Problemen die numerischen Ausdrücke nicht mit == bzw. != abzufragen, da oft kleine Ungenauigkeiten von z.B. 1*10^-8 in den ausdrücken zu finden sind und somit == nicht erfüllt wird!
Das

Code: Alles auswählen

if (-1 < quadrat-wurzel_aus < 1)
war eine Änderung, die ich probiert habe, weil ich das mit den Ungenauigkeiten vermutet hatte. Versehentlich hatte ich also nicht die originale Version ins Posting kopiert. Ist ja aber auch kommentiert.

Wie kann ich denn diese Ungenauigkeiten umgehen? Gibt es einen Ungefähr-Operator?

Benutzeravatar
Dookie
Beiträge: 1104
Registriert: 17.02.2002 20:38:19
Wohnort: Salzburg
Kontaktdaten:

Beitrag von Dookie » 06.06.2003 21:12:15

Hi,

du könntest einen "ungefähr" Operator mit einer Funktion simulieren.

in Python würd ich den so machen

Code: Alles auswählen

nearly = lambda a,b,precision: abs(a-b) < precision
>>> x = 12345.6789
>>> y = 12345.6788
>>> print nearly(x,y,0.001)
1
Das Prinzip ist ganz einfach, ziehe den wert b vom wert a ab und vergleiche die absolute Differenz mit Deinem Schwellwert.

Gruß

Dookie

Benutzeravatar
jogix
Beiträge: 776
Registriert: 05.10.2002 20:08:16
Wohnort: Lampertheim
Kontaktdaten:

Beitrag von jogix » 08.06.2003 09:57:17

Hi,

ich jetzt nicht die Absolutwertberechnung von C++, würde das aber entsprechend so aufrufen:

Code: Alles auswählen

if (abs(quadrat-wurzel_aus) < delta ) ...
Damit bildest Du den Betrag der Differenz, die ja um die Null herum sein sollte. Durch den Betrag ist das ganze immer positiv und somit sinnvoll gegen einen kleinen Wert Delta zu prüfen.
Delta kannst Du als Konstante definieren und dann mit der Genauigkeit spielen: z.B.
delta = 1e-5;
cheers,
Jochen
___________________________________________________
Testing can prove the presence of bugs, but not their absence. -- Dijkstra

Benutzeravatar
Sebastian.S
Beiträge: 437
Registriert: 13.04.2003 13:17:41

Beitrag von Sebastian.S » 08.06.2003 10:42:39

Vielen Dank für die Antworten...


Leider habe ich da so ein Problem mit der abs-Funktion:

Code: Alles auswählen

test1.c: In function `int main(...)':
test1.c:15: warning: `double' used for argument 1 of `abs(int)'
Also erwartet abs einen integer-Wert, womit die Genauigkeit aber wieder hinfällig wäre.

keyem
Beiträge: 303
Registriert: 23.08.2002 07:50:28
Wohnort: Berlin

Beitrag von keyem » 08.06.2003 12:13:17

"fabs" löst Dein Problem!

Viel Erfolg weiterhin,
keyem

Benutzeravatar
Sebastian.S
Beiträge: 437
Registriert: 13.04.2003 13:17:41

Beitrag von Sebastian.S » 08.06.2003 13:13:00

Falls es jemanden interessiert, stelle ich das Programm einfach mal hierher:

Code: Alles auswählen

#include <iostream>
#include <cmath>

 using namespace std;
// g++ -I/usr/include/g++-3/ -o test3 test1.c



 void main(void) {

 double wurzel_aus=2, startwert=2, quadrat=4;
 unsigned int durchlauf=65535, durchlauf2=0;
 double delta;

 cout << "Bitte geben Sie die zu radizierende Zahl ein: _" ;
 cin >> wurzel_aus;
 cout << "\nStartwert? _";
 cin >> startwert;
  cout << "\nGenauigkeit? (in 1*10 ^ -x) _";
 cin >> delta;

 delta=(-1)*fabs(delta);
delta=1*pow(10, delta);
//cout << delta;


	while (fabs(quadrat-wurzel_aus) > delta) {
		startwert=((startwert+wurzel_aus/startwert)/2);
		quadrat=startwert*startwert;
		 ++durchlauf2;
	}

 cout << "\n\nErgebnis: " << startwert << endl << (startwert*startwert) << endl << durchlauf2 << endl<<quadrat<<endl;

 }
Humanity stands at a crossroads. [...] Will we evaluate, learn and profit
from [...] these new ideas and opportunities, or will we [...] suppress all of this in favor of
intellectually weak, [...] and sometimes brutally unfair
and inefficient policies?

Antworten