?
So hab das Problem gelöst, es lag an der neuen float funktion::f_strich_von(float)...
Naja wer die Funktionen interessant findet kann sie sich ja mal ansehen, aber im moment fehlt noch eine benutzerobverfläche und die funktion, die die kurvendiskussion ausgibt... ich werde auchnoch integralrechnungen implementieren und so zeug, aber however das problem is gelöst
hauen sie rein!
hier ist der code:
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
class funktion
{
private:
int grad;
float* x;
public:
funktion();
funktion(int g) { grad = g; x = new float[grad + 1]; }
void give(int index, float wert) { *(x + index) = wert; }
~funktion() { delete x; }
void spell(float) const;
void spell(float, int) const;
void spell_int(float) const;
float* f_von_x();
void newtoneingabe() { newtoneingabe(f_von_x()); }
void newtoneingabe(float*);
void show_term() { show_term(f_von_x()); }
void show_term(float*);
void show_term(bool b) { show_term(f_von_x(), b); }
void show_term(float*, bool);
float f_von(float fl) { f_von(f_von_x(), fl); }
float f_von(float*, float);
float f_strich_von(float fl) { f_strich_von(f_von_x(), fl); }
float f_strich_von(float*, float);
float approx(float fl) { approx(f_von_x(), fl); }
float approx(float*, float);
float newton(float fl) { newton(f_von_x(), fl); }
float newton(float*, float);
void PQ_out() { PQ_out(f_von_x()); }
void PQ_out(float*);
float* PQ() { PQ(f_von_x()); } // s.u.
float* PQ(float*); // <- float* (das 1.) ist hier keine funktion
float* restpolynom(float fl) { restpolynom(f_von_x(), fl); }
float* restpolynom(float*, float);
float* tangente(float fl) { tangente(f_von_x(), fl); }
float* tangente(float*, float);
float* ableiten() { ableiten(f_von_x()); }
float* ableiten(float*);
float* ableiten(int n) { ableiten(f_von_x(), n); }
float* ableiten(float*, int);
float* nullstellen() { nullstellen(f_von_x()); } // s.u.
float* nullstellen(float*); // <- float* (das 1.) ist hier keine funktion
float* plus_NS(float*, float); // beide float* keine fnkt.
void show_NS() { show_NS(f_von_x()); }
void show_NS(float*); // s.o.
void draw(float*, float, float, float, float);
void draw(float*, float*, float, float, float, float);
void draw(float x1, float x2, float y1, float y2) { draw(f_von_x(), x1, x2, y1, y2); }
void draw(float* f, float x2, float y2) { draw(f, 0, x2, 0, y2); }
void draw(float x2, float y2) { draw(f_von_x(), 0, x2, 0, y2); }
void draw(float* f) { draw(f, -5, 5, -5, 5); }
void draw() { draw(f_von_x(), -5, 5, -5, 5); }
};
int main()
{
while (true)
{
funktion* f = new funktion;
cout << endl << "f(x) = ";
f -> show_term();
//f -> draw(x1, x2, y1, y2);
f -> newtoneingabe();
delete f;
cout << endl;
}
system("PAUSE");
return 0;
}
funktion :: funktion()
{
cout << "Funktionseingabe" << endl;
cout << "grad:\t";
cin >> grad;
x = new float[grad + 1];
for (int i = 0; i <= grad; i ++)
{
cout << "a" << grad - i << ":\t";
cin >> x[i];
}
}
void funktion :: newtoneingabe(float* f)
{
bool vomfeinsten;
cout << "Newtonsche Naeherung" << endl << " [1] Textausgabe";
cout << endl << " [0] Standartausgabe" << endl << " ";
cin >> vomfeinsten;
if (vomfeinsten) cout << endl << "f von x ist gleich ";
else cout << endl << "f(x) = ";
show_term(f_von_x(), vomfeinsten);
cout << endl << endl << "x-wert fuer nullstellenapproximation: ";
float nullstelle;
cin >> nullstelle;
if (vomfeinsten)
{
cout << endl << "die naechste nullstelle zu ";
spell(nullstelle);
cout << " liegt bei x gleich ";
spell(approx(f, nullstelle));
cout << ".";
}
else
{
cout << endl << "naechste nullstelle zu " << nullstelle << ": ";
cout << approx (f, nullstelle);
}
cout << endl << endl;
}
void funktion :: show_term(float* f)
{
if (*f > 0)
{
for (int i = 1; i <= *f; i ++)
{
if (f[i] != 0)
{
if (i > 1) cout << " ";
int exponent = (int)*f - i;
if (f[i] != 1 && f[i] != -1)
{
if (i > 1 && f[i] > 0) cout << "+ " << f[i];
if (i == 1 && f[i] > 0) cout << f[i];
if (f[i] < 0) cout << "- " << -f[i];
}
else if (i > 1 && f[i] > 0) cout << "+ ";
else if (f[i] < 0) cout << "- ";
if (exponent == 0 && f[i] == -1
|| exponent == 0 && f[i] == 1) cout << 1;
if (exponent > 0) cout << "x";
if (exponent > 1) cout << "^" << exponent;
}
}
}
else cout << 0;
}
void funktion :: show_term(float* f, bool b00l)
{
if (!b00l) show_term(f);
if (b00l)
{
if (*f > 0)
{
for (int i = 0; i < *f; i ++)
{
if (f[i + 1] != 0)
{
if (i > 0) cout << " ";
int exponent = (int)*f - 1 - i;
if (f[i + 1] != 1 && f[i + 1] != -1)
{
if (i > 0 && f[i + 1] > 0)
{
cout << "plus ";
spell(f[i + 1]);
cout << " ";
}
if (i == 0 && f[i + 1] > 0)
{
spell(f[i + 1]);
cout << " ";
}
if (f[i + 1] < 0)
{
cout << "minus ";
spell(- f[i + 1]);
cout << " ";
}
}
else if (f[i + 1] == -1) cout << "minus ";
else if (i > 0 && f[i + 1] == 1) cout << "plus ";
if (exponent == 0 && f[i + 1] == 1 || exponent == 0 && f[i + 1] == -1)
{
cout << "eins";
}
if (exponent > 0) cout << "x";
if (exponent > 1)
{
cout << " hoch ";
spell(exponent);
}
}
}
}
else cout << "null";
}
}
void funktion :: spell(float zahl) const
{
spell (zahl, 2);
}
void funktion :: spell(float zahl, int nachkommastellen) const
{
if (zahl < 0) // falls zahl < 0
{
cout << "minus ";
zahl *= -1;
}
zahl *= pow((float)10, nachkommastellen); // erstmal runden
zahl = floor(zahl + 0.5);
zahl /= pow((float)10, nachkommastellen);
int i = 1;
float zahl_original = zahl;
spell_int((int)zahl); // vorm komma
zahl -= (int)zahl;
if (zahl != 0) cout << "-komma"; // das komma
while (i <= nachkommastellen && zahl != 0) // nachm komma
{
if (zahl != 0)
{
zahl *= 10;
cout << "-";
spell_int((int)zahl);
zahl -= (int)zahl;
}
i ++;
}
}
void funktion :: spell_int(float zahl) const
{
switch ((int)zahl) // 0-12; 17; 20; 30; 40; 50; 60; 70; 80; 90; 100;
{ // 1.000; 1337; 1000000; 71349315; 1000000000;
case 0: cout << "null"; break;
case 1: cout << "eins"; break;
case 2: cout << "zwei"; break;
case 3: cout << "drei"; break;
case 4: cout << "vier"; break;
case 5: cout << "fuenf"; break;
case 6: cout << "sechs"; break;
case 7: cout << "sieben"; break;
case 8: cout << "acht"; break;
case 9: cout << "neun"; break;
case 10: cout << "zehn"; break;
case 11: cout << "elf"; break;
case 12: cout << "zwoelf"; break;
case 17: cout << "siebzehn"; break; // wäre sonst siebENzehn
case 20: cout << "zwanzig"; break;
case 30: cout << "dreissig"; break;
case 40: cout << "vierzig"; break;
case 50: cout << "fuenfzig"; break;
case 60: cout << "sechszig"; break;
case 70: cout << "siebzig"; break;
case 80: cout << "achtzig"; break;
case 90: cout << "neunzig"; break;
case 100: cout << "hundert"; break;
case 1000: cout << "tausend"; break;
case 1000000: cout << "eine million"; break;
case (int)1e9: cout << "eine milliarde"; break;
default:
if (zahl > 12 && zahl < 20) // 13-19
{
spell_int(zahl - 10);
spell_int(10);
}
for (int i = 20; i <= 90; i += 10) // 21-99
{
if (zahl > i && zahl < i + 10)
{
if (zahl - i != 1) spell_int(zahl - i);
else cout << "ein";
cout << "und";
spell_int(i);
}
}
if (zahl > 100 && zahl < 1000) // 101-999
{
if ((zahl-(int)zahl%100)/100 != 1) spell_int((zahl-(int)zahl%100)/100);
else cout << "ein";
cout << "hundert";
if ((int)zahl % 100 != 0) spell_int((int)zahl % 100);
}
if (zahl > 1000 && zahl < 1000000) // 1001-999999
{
if ((zahl-(int)zahl%1000)/1000!=1) spell_int((zahl-(int)zahl%1000)/1000);
else cout << "ein";
cout << "tausend";
if ((int)zahl % 1000 != 0) spell_int((int)zahl % 1000);
}
if (zahl > 1e6 && zahl < 1e9) // 1000001-999999999
{
spell_int((zahl - (int)zahl % (int)1e6) / (int)1e6);
cout << "millionen";
if ((int)zahl % (int)1e6 != 0) spell_int((int)zahl % (int)1e6);
}
if (zahl > 1e9 && zahl < 1e12) // 1000000001-grenze
{
spell_int((zahl - (int)zahl % (int)1e9) / (int)1e9);
cout << "milliarden";
if ((int)zahl % (int)1e9 != 0) spell_int((int)zahl % (int)1e9);
}
}
}
float funktion :: f_von(float* f, float x_wert)
{
float erg = 0;
for (int i = 1; i <= *f; i ++) erg += f[i] * pow(x_wert, ((*f - 1) - i + 1));
return erg;
}
float funktion :: f_strich_von(float* f, float x_wert)
{
float erg = 0;
for (int i = 1; i <= *f - 1; i ++)
erg += f[i] * ((*f - 1) - (i - 1)) * pow(x_wert, ((*f - 1) - i));
return erg;
}
float funktion :: newton(float* f, float x0)
{
if (f_strich_von(f, x0) != 0) x0 = x0 - f_von(f, x0) / f_strich_von(f, x0);
return x0;
}
float funktion :: approx(float* f, float x0)
{
float erg = x0;
if (f_strich_von(f, erg) == 0) erg += 1e-2;
if (x0 - newton(f, x0 + 1e-2) > 0 && x0 - newton(f, x0 - 1e-2) < 0 ||
x0 - newton(f, x0 + 1e-2) < 0 && x0 - newton(f, x0 - 1e-2) > 0) erg +=1e-2;
while (erg != newton(f, erg)) erg = newton(f, erg);
return erg;
}
void funktion :: PQ_out(float* f)
{
cout << "PQ-Formel" << endl;
if (*PQ(f) == 0) cout << "L = { }" << endl << endl;
if (*PQ(f) == 2)
{
if (PQ(f)[1] != PQ(f)[2])
{
cout << "N1 ( " << PQ(f)[1] << " | 0 )" << endl;
cout << "N2 ( " << PQ(f)[2] << " | 0 )" << endl << endl;
}
else cout << "N ( " << PQ(f)[1] << " | 0 )\t<- doppelt\n\n";
}
}
float* funktion :: PQ(float* f)
{
int nullstellen = 0;
float* erg;
if (*f == 3)
{
float temp_x[2] = {f[2] / f[1], f[3] / f[1]};
if (pow(pow(temp_x[0] / 2, 2) - temp_x[1], (float)0.5) >= 0)
{
nullstellen += 2;
erg = new float[nullstellen + 1];
*erg = nullstellen;
*(erg + 1) = - temp_x[0] / 2 - pow(pow(temp_x[0] / 2, 2) - temp_x[1], (float)0.5);
*(erg + 2) = - temp_x[0] / 2 + pow(pow(temp_x[0] / 2, 2) - temp_x[1], (float)0.5);
}
else
{
erg = new float[nullstellen + 1];
*erg = 0;
}
}
else
{
erg = new float[nullstellen + 1];
*erg = 0;
}
return erg;
}
float* funktion :: f_von_x()
{
float* f = new float[grad + 2];
*f = grad + 1;
for (int i = 1; i <= grad + 1; i ++) f[i] = x[i - 1];
return f;
}
float* funktion :: restpolynom(float* vorher, float nullstelle)
{
float* nachher = new float[(int)*vorher];
*nachher = *vorher - 1;
nachher[1] = vorher[1];
for (int i = 2; i <= *vorher - 1 ; i ++)
{
nachher[i] = nullstelle * nachher[i - 1] + vorher[i];
}
return nachher;
}
float* funktion :: tangente(float* f, float TS)
{
float* p;
if (f_strich_von(f, TS) == 0)
{
p = new float[2];
p[0] = 1;
p[1] = f_von(f, TS);
}
else
{
p = new float[3];
p[0] = 2;
p[1] = f_strich_von(f, TS);
p[2] = -f_strich_von(f, TS) * TS + f_von(f, TS);
}
return p;
}
float* funktion :: ableiten(float* f)
{
float* f_strich;
if (*f > 0)
{
f_strich = new float[(int)*f];
*f_strich = *f - 1;
for (int i = 1; i <= *f; i ++) f_strich[i] = f[i] * (*f - i);
}
else f_strich = f;
return f_strich;
}
float* funktion :: ableiten(float* f, int n)
{
for (int i = 0; i < n; i ++) f = ableiten(f);
return f;
}
float* funktion :: nullstellen(float* f)
{
float* NS = new float;
*NS = 0;
while(*f > 1)
{ // rausfinden ob überhaupt nullstelle am start !!!
NS = plus_NS(NS, approx(0));
f = restpolynom(f, approx(0));
}
return NS;
}
float* funktion :: plus_NS(float* list, float NS)
{
float new_list[(int)*list + 2];
*new_list = *list + 1;
for (int i = 1; i <= *list; i ++) new_list[i] = list[i];
new_list[(int)*new_list] = NS;
list = new_list;
// bubble sort:
float temp;
for (int i = (int)*list; i > 1; i --) if (list[i] < list[i - 1])
{
temp = list[i];
list[i] = list[i - 1];
list[i - 1] = temp;
}
return list;
}
void funktion :: show_NS(float* f)
{
float* NS = nullstellen(f);
for (int i = 0; i < *NS; i++)
{
cout << "N" << i + 1 << ": " << *(NS + i + 1) << endl;
}
}
void funktion :: draw(float* f, float x1, float x2, float y1, float y2)
{
int hoehe = 47, breite = 79;
char feld[hoehe][breite];
for (int i = 0; i < hoehe; i++)
{
for (int j = 0; j < breite; j++)
{
feld[i][j] = ' ';
/*fill*/ for (float k = x1 + (x2 - x1) / breite * j; k < x1 + (x2 - x1) / breite * (j + 1); k += (x2 - x1) / breite / 100)
{
if (f_von(f, k) <= y2 - (y2 - y1) / hoehe * (i + 1)
&& y2 - (y2 - y1) / hoehe * i <= 0
&& k > approx(x1) && k < approx(x2)
|| f_von(f, k) > y2 - (y2 - y1) / hoehe * i
&& y2 - (y2 - y1) / hoehe * (i + 1) > 0
&& k > approx(x1) && k < approx(x2))
feld[i][j] = 176;
}
if (x1 + (x2 - x1) / breite * j <= 0 && x1 + (x2 - x1) / breite * (j + 1) > 0)
feld[i][j] = 179;
if (y2 - (y2 - y1) / hoehe * i > 0 && y2 - (y2 - y1) / hoehe * (i + 1) <= 0)
feld[i][j] = 196;
if (x1 + (x2 - x1) / breite * j <= 0 && x1 + (x2 - x1) / breite * (j + 1) > 0
&& y2 - (y2 - y1) / hoehe * i > 0 && y2 - (y2 - y1) / hoehe * (i + 1) <= 0)
feld[i][j] = 197;
for (float k = x1 + (x2 - x1) / breite * j; k < x1 + (x2 - x1) / breite * (j + 1); k += (x2 - x1) / breite / 100)
{
if (f_von(f, k) <= y2 - (y2 - y1) / hoehe * i
&& f_von(f, k) > y2 - (y2 - y1) / hoehe * (i + 1))
feld[i][j] = 219;
}
}
}
for (int i = 0; i < hoehe; i++)
{
cout << endl;
for (int j = 0; j < breite; j++)
{
cout << feld[i][j];
}
}
}
void funktion :: draw(float* f, float* g, float x1, float x2, float y1, float y2)
{
int hoehe = 47, breite = 79;
char feld[hoehe][breite];
for (int i = 0; i < hoehe; i++)
{
for (int j = 0; j < breite; j++)
{
feld[i][j] = ' ';
/*fill*/ for (float k = x1 + (x2 - x1) / breite * j; k < x1 + (x2 - x1) / breite * (j + 1); k += (x2 - x1) / breite / 100)
{
if (f_von(f, k) <= y2 - (y2 - y1) / hoehe * (i + 1)
&& f_von(g, k) > y2 - (y2 - y1) / hoehe * i
|| f_von(f, k) > y2 - (y2 - y1) / hoehe * i
&& f_von(g, k) <= y2 - (y2 - y1) / hoehe * (i + 1))
feld[i][j] = 176;
}
if (x1 + (x2 - x1) / breite * j <= 0 && x1 + (x2 - x1) / breite * (j + 1) > 0)
feld[i][j] = 179;
if (y2 - (y2 - y1) / hoehe * i > 0 && y2 - (y2 - y1) / hoehe * (i + 1) <= 0)
feld[i][j] = 196;
if (x1 + (x2 - x1) / breite * j <= 0 && x1 + (x2 - x1) / breite * (j + 1) > 0
&& y2 - (y2 - y1) / hoehe * i > 0 && y2 - (y2 - y1) / hoehe * (i + 1) <= 0)
feld[i][j] = 197;
for (float k = x1 + (x2 - x1) / breite * j; k < x1 + (x2 - x1) / breite * (j + 1); k += (x2 - x1) / breite / 100)
{
if (f_von(f, k) <= y2 - (y2 - y1) / hoehe * i
&& f_von(f, k) > y2 - (y2 - y1) / hoehe * (i + 1)
|| f_von(g, k) <= y2 - (y2 - y1) / hoehe * i
&& f_von(g, k) > y2 - (y2 - y1) / hoehe * (i + 1))
feld[i][j] = 219;
}
}
}
for (int i = 0; i < hoehe; i++)
{
cout << endl;
for (int j = 0; j < breite; j++)
{
cout << feld[i][j];
}
}
}