Java / BlueJ: Wo ist hier der Fehler?
Ich habe folgendes Programm geschrieben:
public class Formel {
private int c;
private int p;
private int k;
private boolean ergebnis;
public Formel() {
double formel = Math.pow(c, 3) - 3 * Math.pow(c, 2) * (p -k) + 3 * c * (Math.pow(p, 2) - Math.pow(k, 2)) - (Math.pow(p, 3) + Math.pow(k, 3));
p = 2;
k = 1;
boolean ergbnis = false;
for (formel = 0;;) {
do {
Math.pow(-4 * Math.pow(k, 3) + 9 * Math.pow(k, 2) * p + Math.pow(-16 * Math.pow(k, 6) + 24 * Math.pow(k, 5) * p + 9 * Math.pow(k, 4) * Math.pow(p, 2) - 22 * Math.pow(k, 3) * Math.pow(p, 3) + 9 * Math.pow(k, 2) * Math.pow(p, 4), 0.5) - 3* k * Math.pow(p, 2), 1 / 3); // divided by Math.pow(2, 1/3);
p++;
k++;
}
while (ergebnis = false);
if (ergebnis = true) {
System.out.println(c);
System.out.println(p);
System.out.println(k);
break;
}
}
}
}
Hier:
3 * k* Math.pow(p, 2), 1 / 3); // divided by Math.pow(2, 1 / 3)
will ich, dass die linke Seite (also den ganzen linken Term beginnend mit Math.pow(-4Math.pow(k,3)...) durch die rechte geteilt wird. Also soll da stehen:
Math.pow(-4 * Math.pow(k, 3) + 9 * Math.pow(k, 2) * p + Math.pow(-16 * Math.pow(k, 6) + 24 * Math.pow(k, 5) * p + 9 * Math.pow(k, 4) * Math.pow(p, 2) - 22 * Math.pow(k, 3) * Math.pow(p, 3) + 9 * Math.pow(k, 2) * Math.pow(p, 4), 0.5) - 3 * k * Math.pow(p, 2), 1 / 3) / Math.pow(2, 1 / 3);
Jedoch ist das Problem dass er das geteilt Zeichen nicht als Statement sieht? Was ist hier falsch bzw. wie kann ich das korrigieren?
4 Antworten
Man kann den Quellcode gar nicht lesen.
Wähle entweder zwischen dem Veröffentlichen des Quellcodes auf Seiten wie www.pastebin.com oder verwende die Quellcode-Funktion* von GuteFrage.net !
alex
* Beispiel :
class Test{
public static void Main(String[] args){
System.out.println("Hier wird die Quellcode-Formatierung von GF verwendet !");
}
}
nvm schau über oder unter deinem komentar habe da zwei bilder gepostet
In Fragen / Antworten wird der Quellcode nach Abschicken mit Syntax Highlighting versehen und auch generell ändert sich die Formatierung (keine großen Abstände zwischen Zeilen etc.). Mehr übernimmt die Funktion aber nicht. Einrückungen musst du selbst setzen.
Nimmst du an einem Perl-ähnlichen Contest teil (Wer schreibt den am wenigsten nachvollziehbaren Code)? Gerade hier solltest du doch längst gemerkt haben, dass der Quellcode so gut wie gar nicht mehr nachvollziehbar und die Fehlerrisikoquote dadurch sehr hoch angestiegen ist.
- Benenne deine Elemente vernünftig. Das bedeutet, dass an ihrem Namen eindeutig erkennbar ist, was sie beinhalten oder tun. Dies tut keine deiner Variablen. Das Gleiche gilt für den Klassennamen.
- Teile deine Formel in Teilstücke / einzelne Terme auf. Jeder Term bekommt einen nachvollziehbaren Namen. Die Berechnung könnte gar in eine eigene Methode geschrieben werden, die dann nur noch den errechneten double-Wert zurückgibt.
- Setze Leerzeichen zwischen Operatoren.
- Entferne unnötige leere Zeilen (bei dir Zeile 3-4 und 9) und achte stattdessen darauf, dass jede Anweisung in einer eigenen Zeile steht (in der Zeile nach do ist dies nicht gegeben). Halte den K&R-Stil (bzw. 1TBS) ein, wie er in Java verwendet wird.
- Verwende als äußere Schleife eine passende Schleife. Die for-Schleife ist es offensichtlich nicht, denn sie zählt nichts. - Es geht nicht darum, dass es sprachlich funktioniert, sondern um die Lesbarkeit des Codes. while macht schneller deutlich, dass die Anzahl an Iterationen noch unbekannt ist.
Wenn du diese Punkte befolgt hast, wird es leichter fallen, dein Problem zu lösen, da die zuständige Zeile für die Division dann nur noch so in der Art aussehen sollte:
double result = someDividend / someDivisor;
Zu beachten ist an dieser Stelle, dass entweder Dividend oder Divisor vom Typ double sein muss, um ein double-präzises Ergebnis zu bekommen.
Fehler / Probleme, die mir bereits so aufgefallen sind:
a) Erst berechnest du irgendetwas:
double formel = // fancy calculation ...
// ...
for (formel = 0;;) {
und nur wenige Zeilen später wirfst du dies wieder weg, indem du es mit 0 überschreibst.
b) Evt. wolltest du hier die Variable ergebnis definieren...?
boolean ergbnis = false;
Das müsste dann eher so aussehen:
ergebnis = false;
c) Deine innere Schleife wird nur ein einziges Mal laufen. Der Grund ist die Bedingung:
while (ergebnis = false);
Die Variable ergebnis wird erst auf den Wert false gesetzt und dann mit true verglichen:
(ergebnis = false) == true
Du wolltest an dieser Stelle ganz sicher einen Vergleich vornehmen. Der Vergleichsoperator wird mit zwei Gleichheitszeichen geschrieben:
while (ergebnis == false);
d) Sobald du die Anwendung so laufen lässt, wird sie sich mit einem Laufzeitfehler selbst erhängen, denn innerhalb der Schleife ändert sich der Wert von ergebnis nicht. Da der Standardwert für boolsche Variablen false ist, wird die Bedingung dauerhaft erfüllt.
e) Eine Zeile nach der Schleife machst du den gleichen Fehler wie bei c).
if (ergebnis = true) {
In dem Fall wird die Bedingung in jedem Fall erfüllt, da der Variable ergebnis der Wert true zugewiesen wird.
Wenn dir dieser Fehler noch öfter passiert, gewöhne dir die Yoda-Schreibweise an. Der konkrete Wert wird als erstes aufgeführt.
if (true == ergebnis)
Da hier ein Zuweisungsoperator zum Compilerfehler führen würde, eine Erinnerung dir gegeben sei, bevor kompilieren du kannst.
f) Jetzt schauen wir uns mal dein Schleifenkonstrukt genauer an, unter der Annahme, es sei nach dem oberen Kriterien hin bereits korrigiert:
for (formel = 0;;) {
do {
// ...
}
while (ergebnis == false);
if (ergebnis == true) {
// ...
break;
}
}
Frage 1: Wozu ist das if notwendig?
Damit do-while durchbrochen werden kann, muss die Variable ergebnis den Wert true haben. Das heißt, nach Beendigung der do-while hat sie diesen Zustand immer, es geht nicht anders. Der Zustand, der logisch klar ist, muss nicht nochmals überprüft werden. Das if kann raus.
Frage 2: Wozu ist die äußere Schleife notwendig?
Da der ehemalige Körper von if immer nach der do-while ausgeführt wird, kommt es auch zur Ausführung des break-Befehls. Das heißt, schon im ersten Durchlauf der äußeren Schleife wird die Anweisung gegeben: Verlasse die Schleife wieder. Für nur einen Durchlauf wird aber keine Schleife benötigt. Sie kann raus, ihre Startbedingung wird ja eh erfüllt. Übrig bleibt nur der Inhalt ihres Körpers.
g) Was auch immer du da drin tust:
do {
Math.pow(-4 * Math.pow(k, 3) + 9 /* etc. ... */
es wird einmal ausgeführt (sofern es das erfolgreich ausführen kann) und danach gleich wieder verworfen. Du speicherst dir das Ergebnis nicht.
Du solltest an der Lesbarkeit deines Codes arbeiten. Mache hinter jedem Aufruf von Math.pow(), hinter jeder Variablen und hinter jedem mathematischen Operator ein Leerzeichen. Dann kannst du den Fehler ggf. leichter finden.
Außerdem ist etwas wie
-4Math.pow(k,3)
eigentlich nicht möglich in Java. Ein Wunder, dass das bei dir kompiliert ...
Kleiner Tipp: teile die Formel auf und weise sie mehreren Variablen zu. Denn wenn du die Formel so lässt, wie sie aktuell ist, wird es beinahe unmöglich sein, sie zu verstehen und mögliche Fehler zu finden.
so besser? @AlexBy Java
![- (Java, Informatiker, BlueJ)](https://images.gutefrage.net/media/fragen-antworten/bilder/297971360/0_big.png?v=1544043661000)
![- (Java, Informatiker, BlueJ)](https://images.gutefrage.net/media/fragen-antworten/bilder/297971360/1_big.png?v=1544043661000)
Ich verstehe nicht ganz wie das mit der quellcode funktion funktioniert wenn ich meien quellcode darein poste dann ändert sich nichts