Funktionsberechnung

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hallo,
ich soll für meinen Mathe Lehrer ein Programm schreiben, welches alle Möglichkeiten, für die Variablen a und b der Funktion Funktion f(x) = ax^4 + bx^3, in einem Intervall von -100 bis 100 durchprobiert. Dabei soll die Funkton immer durch den Punkt (2|4) gehen. D.h. man hat praktisch die Gleichung a*16 + b*8 = 4 und muss dann verschiedene Werte für a und b einsetzen. Das Programm habe ich schon fertig geschrieben, allerdings gibt es mir keinen einzigen Wert aus. Hier ist der Quellcode meines Programms:

Code:
public class Funktionsberechnung
{
  public static void main (String[]arguments)
  {
    double a, b;
    a = -100;
    b = -100;


    while (a <= 100)
    {
      while (b <= 100)
      {
        if((a*16 + b*8) == 4)
        {
          System.out.println("a = " + a + "   b = " + b);
        }
         b = b + 1;
      }

      a = a + 1;
    }

  }
}

Es wäre sehr nett von euch wenn ihr mir sagen könntet wo der Fehler liegt.

Schon mal Danke für die Antworten.

mit freundlichen Grüßen

S3rious
 

mikachu

Top Contributor
tipp: schreibtischtest ;)

wird denn deine variable b nach der inneren schleife wieder auf den ursprungswert zurückgesetzt, damit sie bei dem nächsten a-schleifen-durchlauf wieder angefasst wird??? ;)

das zum funktionellen...
jetzt zum logischen...

rechne mal:
a=1 und b=-1 ==> 16 - 8 = 8
a=1 und b=-2 ==> 16 - 16 = 0

es wird NIEMALS das ergebnis 4 erreicht !!!


also den laufwert von a und b etwas feiner machen -> du arbeitest ja schon mit double's, als nimm 0.5 oder 0.25 oder noch feiner... aber mit 0.1 kommt nix raus, da interne rundungsfehler... warum? versuch mal 0.1 binär darzustellen ;)
 

tfa

Top Contributor
Grundsätzlich gibt es hier zwei Probleme:

Fließkommazahlen (double) sollten niemals mit == auf Gleichheit verglichen werden.
Durch die interne Darstellung der Dezimalzahlen im Binärformat kommt es zu
Ungenauigkeiten, so dass zwei double, die eigentlich gleich sein müssten,
intern doch verschieden dargestellt werden.

Zweitens solltest Du Dir die Schleife nochmal ansehen. Was passiert mit b, wenn
die innere Schleife abgearbeitet ist und das nächste a genommen wird?

tfa
 

mikachu

Top Contributor
wenn du schon double mit integer vergleichen musst, und auf genauigkeitsfehler verzichten kannst, dann caste einfach deine berechnung auf integer!
 

jPat

Bekanntes Mitglied
bei solchen vergleichen nimmt man ein "epsilon" , welches die genauigkeit angibt. zb

a==b vergleich
wird zu
(a-b) < epsilon && (a-b)*-1 < epsilon

Da hierbei "um 0" herum geprüft wird.
 
S

SlaterB

Gast
>> (a-b) < epsilon && (a-b)*-1 < epsilon

naja, ob das klappt? ;) (edit: mist, klappt ja tatsächlich ;) )

Math.abs(a-b) < epsilon
 

Marco13

Top Contributor
Genaugenommen sogar
Math.abs(a-b) < epsilon * Math.abs(a);
schließlich werden die Zahlen mit steigender Größe immer ungenauer, und das absolute epsilon damit relativ immer kleiner...
 

jPat

Bekanntes Mitglied
Marco13 hat gesagt.:
Genaugenommen sogar
Math.abs(a-b) < epsilon * Math.abs(a);
schließlich werden die Zahlen mit steigender Größe immer ungenauer, und das absolute epsilon damit relativ immer kleiner...

das würd ich lieber sein lassen ....

falls epsilon = 0,1 und a = 10000

.... :wink:
 
G

Guest

Gast
Scon mal Danke für die Antworten.
Ich habe den Code mal überarbeitet:

Code:
public class Funktionsberechnung
{
  public static void main (String[]arguments)
  {
  
    for(double a = 0; a <= 100; a = a + 0.01)
    {
      for(double b = 0; b <= 100; b = b + 0.01)
      {
        if((a*16 + b*8) == 4)
        {
          System.out.println("a = " + a + "   b = " + b);
        }

      }


    }

  }
}

Kann mir einer von euch mal genau erklären wie das mit der ath.abs funktioniert. Sonst bekomm ich nämlich nu Werte mit X Nachkommastellen.


mfg

S3rious
 

jPat

Bekanntes Mitglied
Es kommt ja auf die Schrittweite an.
und ob a bzw b soooo groß wird ist fraglich. im Normalfall bekommt man diese Art von Rechnungen auch nicht mit solchen Schleifen heraus, sondern geht dort Iterativ heran. Siehe Newton verfahren o.ä.
 
S

SlaterB

Gast
Code:
public static double abs(double a) {
        return (a <= 0.0D) ? 0.0D - a : a;
    }
 

Marco13

Top Contributor
jPat hat gesagt.:
Marco13 hat gesagt.:
Genaugenommen sogar
Math.abs(a-b) < epsilon * Math.abs(a);
schließlich werden die Zahlen mit steigender Größe immer ungenauer, und das absolute epsilon damit relativ immer kleiner...

das würd ich lieber sein lassen ....

falls epsilon = 0,1 und a = 10000

.... :wink:

Das epsilon sollte natürlich klein sein. Wie epsilons nunmal so sind :wink: Es soll ja keine absolute Toleranz angegeben sondern nur ein relativer Fehler ignoriert werden, und der Fehler wird bei größeren Zahlen eben größer. Epsilon beschreibt also nur die Größenordnung des Fehlers, mit dem man aufgrund der beschränkten Rechengenauigkeit rechnen muss. Bei float könnte das z.B. 1e-5 sein, bei double vielleicht 1e-9
 

jPat

Bekanntes Mitglied
(a*16 + b*8) == 4) wird zu:
(a*16 + b*8) -4 == 0) und das zu
Math.abs((a*16 + b*8) -4) < epsilon

un mit epsilon kannst du die genauigkeit eingeben. Am besten ist es, wenn du per hand die ein a, b ausrechnest, wo diese Gleichung stimmt, und dir dabei dann dein Epsilon einstellst.
Es würde meiner Meinung nach ein Epsilon von 0.000001 reichen.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben