Intervallschachtelung - Ergebnis ist immer 0
-
Bashar ich rechne mit Variablen ohne ihren Literal zu kennen
Ich hab es so interpretiert, dass Bashar meinte ich hätte den Literal der Variable beim deklarieren direkt initialisiert ( z.b int x = 5 ) und ich damit die Intervallschachtelung gemacht hätte.
Dir ist aber klar, dass lokale Variablen trotzdem mit 0 initialisiert werden müssen?
Nein das war mir nicht bewust, sorry
int up(float u ) { return u<0?u-.5:u+.5; } int down(float d ) { return d<0?d+.5:d-.5; }
Diesen Code habe ich hier zum Runden gefunden : http://www.c-plusplus.net/forum/39342-full
Mir ist auch nicht klar, warum die Funktion
check
nicht gleich die Variable einliest.was meinst du damit ?
-
Zeile 30.
Und es ist schon ein schlechtes Zeichen, wenn du Variablendeklarationen mit einem Kommentar versehen musst, um zu wissen, wofür sie sind...
C++ erlaubt es dir, Variablen überall zu deklarieren! Versuche sie erst zu deklarieren, wenn du ihr auch einen Wert geben kannst. Und vermeide globale Variablen!
-
Diesen Code habe ich hier zum Runden gefunden :
-
Denk nochmal über deine Variablentypen nach. Warum arbeitet check überhaupt mit
float
, wo du nurint
haben willst?Stimmt !
Genaugenommen willst du sogar
unsigned int
haben. Dann fällt auch die Überprüfung auf < 0 weg.unsigned int ??
Welchen Wert hat ergebnis in intervall und wie ändert der sich?
als ich unter Zeile 32 noch
cout << i_mit << endl;
hinzugefügt habe kam trotzdem "Wurzel aus "wurzel" ist 0", also wurde die Schleife theoretisch einfach übersprungen
Und danke für die tollen Tipps ( keine globalen Variablen)
-
Und
if( pow(ergebnis, 2) >= zahl) // das bedeutet auch bei Gleichheit { i_max = i_mit; } else if( pow(i_mit, 2) <= zahl ) // das bedeutet auch bei Gleichheit { i_min = i_mit; } else if( pow(i_mit, 2) == zahl ) // Gleichheit, wie soll dieser Fall denn jemals eintreten, wenn du ihn vorher schon zweimal abgefangen hast? continue; // hier meinst du eigentlich break
Fließkommazahlen auf Gleichheit zu testen geht meist in die Hose, da es immer Rundungs- und Darstellungsfehler gibt.
-
Zu dir Nathan :
Und es ist schon ein schlechtes Zeichen, wenn du Variablendeklarationen mit einem Kommentar versehen musst, um zu wissen, wofür sie sind...
Benutz du etwa keine Kommentare in deinem Quellcode ??
Denkst du nicht auch dass es übersichtlicher ist die Variablen zu kommentieren ??C++ erlaubt es dir, Variablen überall zu deklarieren! Versuche sie erst zu deklarieren, wenn du ihr auch einen Wert geben kannst. Und vermeide globale Variablen!
Die glabalen Variablen habe ich nur deklariert um alle an einem Punkt zu haben. Wenn das Programm fertig ist kann ich sie dann auch an einer anderen Stelle deklarieren
-
continue; // hier meinst du eigentlich break
Dies stand so in meinem C++ Buch, break ist ja eigentlich eher für while-Schleifen, oder ?
Fließkommazahlen auf Gleichheit zu testen geht meist in die Hose, da es immer Rundungs- und Darstellungsfehler gibt.
Ich bin erst seit einigen Stunden im Forum registriert und schon lernt man viel neues dazu
-
My_Ouzo schrieb:
Genaugenommen willst du sogar
unsigned int
haben. Dann fällt auch die Überprüfung auf < 0 weg.unsigned int ??[/quote]
unsigned int: Ganzzahl ohne Vorzeichen. Nur positive Werte.My_Ouzo schrieb:
als ich unter Zeile 32 noch
cout << i_mit << endl;
hinzugefügt habe kam trotzdem "Wurzel aus "wurzel" ist 0", also wurde die Schleife theoretisch einfach übersprungen
Nathan schrieb:
Zeile 30.
Deine Laufbedingung für die Schleife ist falsch. Die Bedingung (f>=i) muss wahr sein, damit die Schleif läuft
Welche Werte hast du i? Ich denke mal mehr als 1.My_Ouzo schrieb:
Benutz du etwa keine Kommentare in deinem Quellcode ??
Denkst du nicht auch dass es übersichtlicher ist die Variablen zu kommentieren ??Gib deinen Variablen vernünftige Namen. Warum nennst du it nicht iterationen?
My_Ouzo schrieb:
Die glabalen Variablen habe ich nur deklariert um alle an einem Punkt zu haben. Wenn das Programm fertig ist kann ich sie dann auch an einer anderen Stelle deklarieren
Nein, das schaffst du nicht.
Wenn du die Variablen da definierst, wo sie gebraucht werden, dann brauchst du keine Kommentare.
Dann sieht man, das es der for-Schleifenzähler ist.My_Ouzo schrieb:
break ist ja eigentlich eher für while-Schleifen, oder ?
Es gibt eigentlich keinen Unterschied zwischen for und while.
-
My_Ouzo schrieb:
Und es ist schon ein schlechtes Zeichen, wenn du Variablendeklarationen mit einem Kommentar versehen musst, um zu wissen, wofür sie sind...
Benutz du etwa keine Kommentare in deinem Quellcode ??
Denkst du nicht auch dass es übersichtlicher ist die Variablen zu kommentieren ??Nein:
for (int i = 0; ...
Jeder weiß sofort, wofür i verwendet wird.
size_t size = calc_size(...
Jeder weiß sofort, was size speichert (ggf. noch zusätzlich const schreiben).
bool is_smaller = a < b;
Ebenfalls klar.
Robert C. MartinClean Code schrieb:
The proper use of comments is to compensate for our failure to express ourself in code.
Nutze Kommentare für Dinge, die du nicht im Code ausdrücken kannst, bpsw.:
... i = size + 1; // wir müssen 1 addieren, da die später aufgerufene Funktion foobar32 ein anderes Intervall erwartet ...
Schreib einfach bei komplexen Programmen bei der Funktionsdekleration hin, was die Funktion macht und was man beim Aufrufen beachten muss (ggf. noch Laufzeitkomplexität und Exceptionsafety).
// macht eine sehr wichtige Aktion mit der übergebenen Variable value // index muss kleiner als size() und ptr, darf nicht null sein! // im Falle eines Fehlers wird value nicht verändert // der zurückgegebene Pointer bleibt für den Rest des Programmes gültig und muss nicht gelöscht werden T* some_func(int &value, std::size_t index, U *ptr);
Man könnte ptr als Referenz übergeben um klar zu machen, dass null nicht erlaubt ist, aber das hab ich jetzt mal weggelassen. Beachte auch, dass ich durch das nutzen des vorzeichenlosen Typen size_t implizit verlange, dass index nicht negativ sein darf, weswegen kein Kommentar notwendig ist.
-
DirkB schrieb:
Es gibt eigentlich keinen Unterschied zwischen for und while.
for (Initialisierung; Test; Fortsetzung) Anweisung
gegenüber
Initialisierung while (Test) { Anweisung Fortsetzung }
Du kannst die beiden Schleifen gegeneinander austauschen.
Es gibt noch einen Unterschied für den Scope (Sichtbarkeitsbereich) der Laufvariablen, wenn du sie bei der Initialisierung auch definierst.for
nimmt man meist, wenn man die Anzahl der Durchläufe vorher weiß.while
nimmt dann in den anderen Fällen.
Das ist kein Zwang. Das kannst du machen wie du möchtest.
-
Von Poitern weiß ich leider noch nichts. Kommt erst in der Fortsetzung meines Buches dran. Außerdem besitze ich das Buch "C++ - Programmieren mit einfachen Beispielen" von Dirk Lous, und habe mich bereits bis "Klassen" / "Strukturen" durchgearbeitet. Als nächstes Kapitel kommt dann auch die objektorientierte Programmierung ins Spiel
-
So...
ich habe jetzt meinen Quellcode überarbeitet, KEINE GLOBALEN VARIABLEN
und noch die anderen Tipps beachtet:#include <iostream> #include <cmath> #include <string> using namespace std; int up(double u ) { return u<0?u-.5:u+.5; } int down(double d ) { return d<0?d+.5:d-.5; } double intervall(double zahl, int i) { double i_min; double i_max; double i_mit; i_max = up(sqrt(zahl)); i_min = down(sqrt(zahl)); int f; for( f = 1; f <= i; f++ ) { i_mit = ( i_min + i_max )/ 2 ; cout << i_mit << endl; if( pow(i_mit, 2) > zahl ) { i_max = i_mit; } else if( pow(i_mit, 2) < zahl ) { i_min = i_mit; } else if( pow(i_mit, 2) == zahl ) continue; } return i_mit; } int check( double x) { int w = 1; while( w != 0) { if( x <= 0 ) { cout << "Bitte geben sie eine Zahl ueber 0 ein :"; cin >> x; } else { w = 0 ; } } return x; } int main() { double ergebnis; double wurzel; int iterationen; cout << "Hallo" << endl; cout << "Programm zu Berechnung einer Wurzel durch Intervallschachtelung" << endl; cout << endl; cout << "Bitte geben sie eine Zahl ein: "; cin >> wurzel ; wurzel = check(wurzel); cout << "Bitte geben sie an wie viele Iterationen durchgefuehrt werden sollen: "; cin >> iterationen ; iterationen = check(iterationen); ergebnis = intervall(wurzel, iterationen); cout << "Die Wurzel aus " << wurzel << " ist " << ergebnis << endl; return 0; }
Wenn ich als wurzel die Zahl 10 Einlese kommt bei 100 Iterationen 3 raus und bei der ersten 2,5 , d.h dass der Intervallanfang auf 2 gerundet wurde und das Ende eben auf 3.
Außerdem bin ich mit ziemlich sicher, dass die Wurzel von 10 nicht 3 ist
-
Was erwartest du, wenn up und down
int
zurück geben?Mach dochkeinen großen Aufwand um die Startwerte
i_max = zahl; i_min = 0;
Mit
break
beendest du die Schleife.
Mitcontinue
läuft sie mit dem nächsten Durchlauf weiter. Nutzlos bei dir, da eh nichts mehr in der Schleife passiert.My_Ouzo schrieb:
...und noch die anderen Tipps beachtet
Wieviel denn? Und wieviel nicht? Da stehst du nicht gut da.