Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
-
Sebastian.S
- Beiträge: 437
- Registriert: 13.04.2003 13:17:41
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??
-
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
-
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;
}
-
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
-
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
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?
-
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
-
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:
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
-
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
-
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?