Implementierung gcd();square()

jono

Top Contributor
Java:
    public static void main(String[] args) {
        System.out.println(gcd(1052, 52));    // 1. Warum wird gcd hier rot unterkringelt und Methode kann in der main nicht ausgeführt werden?
    }

// Fehlermeldung: Cannot make a static reference to the non-static method gcd(int, int) from the type Math

    @Override
    public int gcd(int a, int b) throws IllegalArgumentException {
        if(a == 0 && b == 0) {
            throw new IllegalArgumentException();
        }
        return gcd(b, a % b);                       // 2. Was bewirkt diese Zeile? Wenn b =16 ist und a = 4, wäre 4%16 = 0,25 und 16(b)*0,25 = 4 (gcd)
    }                                                          // jedoch wird mit b mit a%b doch nicht durch diese Zeile mal genommen?

Java:
    public int square(int x) throws IllegalArgumentException {
        if ((int) Math.pow(x, 2) > Integer.MAX_VALUE) {          // Warum wird ".pow"
            throw new IllegalArgumentException();
        }
        return (int) Math.pow(x, 2);                                       // rot unterkringelt?
    }
Vor dem Komma steht doch die Basis und danach folgt der Exponent, was habe ich da falsch gemacht? Mag eine triviale Frage sein, aber kanns mir einfach nicht erklären... -> Fehlermeldung: The method pow(int, int) is undefined for the type Math

Java:
public int sqrt(int x) throws IllegalArgumentException {
        if(x < 0) {
            throw new IllegalArgumentException();
        }
        return Math.sqrt(x);
    }
Fehlermeldung: Cannot make a static reference to the non-static method sqrt(int) from the type Math
 
Zuletzt bearbeitet:
Es fehlt (wenigstens) ein Instanzobject (Fehlermeldung wg. "Non-static method ... in static function"). Kleine Reparatur:
Java:
GCD gcd_object = new GCD();
        System.out.println(gcd_object.gcd(1052, 52));
Das % steht für eine Modulo-Operation : https://de.wikipedia.org/wiki/Division_mit_Rest#Modulo
Und beim Nachstellen (Eclipse, Java 15) ergibt sich bei
Java:
 return gcd(b, a % b);
ebenfalls eine Fehlermeldung: "Exception in thread "main" java.lang.ArithmeticException: / by zero"
 
GCD gcd_object = new GCD(); System.out.println(gcd_object.gcd(1052, 52));
Wieso das denn? Normalerweise ging es immer so, dass man die Methode in der main einfach mit Beispielparametern printen kann? Verstehe den Umstand da jetzt nicht
Habe kein Java 15.
Weiß ich, habe da ein Fehler gemacht und mit Division verwechselt. Aber wieso wird nicht einfach a%b returnt?
ebenfalls eine Fehlermeldung: "Exception in thread "main" java.lang.ArithmeticException: / by zero"
Warum das denn? Und was ist mit Nachstellen gemeint?
 
Zuletzt bearbeitet:
% gibt den Rest einer Ganzzahlen-Division zurück.
Damit hast Du eine Ganzzahlen-Division und dabei darf der Divisor nicht 0 sein.
Wenn bei einer Integer Division (Egal ob / oder %, egal ob Java 15 oder älter) der Divisor 0 ist, dann wird eine ArithmeticException geworfen.

Und zu dem return kommt er auf Grund der Exception nicht mehr:
return gcd(b, a % b);
macht ja folgendes:
1) a % b wird ausgerechnet
2) gcd(a, Ergebnis aus 1) wird aufgerufen
3) return mit Rückgabe von gcd wird ausgeführt

Bei 1) kommt die Exception, daher kommt er nicht zu 2) und 3)
 
Wie konkret muss ich das korrigieren? Soll ich den Variablen Werte zuweisen?
Und zu dem return kommt er auf Grund der Exception nicht mehr
Da heisst wohl irgendeine Klasse von dir auch Math
Nein, es gibt nur eine IntMaths.class, aber nicht nochmal so eine Klasse mit genau demselben Namen

Also mir ist gerade nicht wirklich geholfen.
Java:
    @Override
    public int sqrt(int x) throws IllegalArgumentException {
        if(x < 0) {
            throw new IllegalArgumentException();
        }
        return Math.sqrt(x);
    }
Also ich habe jetzt immer noch das Problem, dass mir Math rot unterkringelt wird.
und, dass
Java:
@Override
    public int square(int x) throws IllegalArgumentException {
        if ((int) Math.pow(x, 2) > Integer.MAX_VALUE) {
            throw new IllegalArgumentException();
        }
        return (int) Math.pow(x, 2);
    }
.pow rot unterkringelt wird. Kann mir bitte jemand etwas konkreter weiterhelfen?
1619187907588.png
Und so sieht die linke Leiste bei mir aus.
 
Du darfst keine Division durch 0 machen! Dein Code ist also so schlicht falsch.

Schau Dir einmal genau an, was der gcd Algorithmus genau machen soll ... Du musst irgend was anderes machen, wenn b 0 ist.

Oder eine andere dumme Frage: Das ist doch eine Rekursion - wo ist die Abbruchbedingung?
 
Doch, es gibt eine Klasse Math, guck dir mal das grau hinterlegte in deinem Screenshot an...
Ich habe davon gesprochen, dass es keine doppelte Benennung einer Klasse mit Math.java gibt @thecain @mrBrown Habe mich gerade vertan und habe was missverstanden, deshalb alles gut
Kannst du denn irgendwas von deinem Code nachvollziehen? zB, was die if-Bedingung besagt?
Ja kann ich nachvollziehen, die if-Bedingung besagt, dass wenn das und das eintritt dass dann die jeweilige Fehlermeldung ausgespuckt wird, was daran soll ich nicht verstehen?
 
Du darfst keine Division durch 0 machen! Dein Code ist also so schlicht falsch.
Java:
@Override
    public int gcd(int a, int b) throws IllegalArgumentException {
       if(a == 0 && b == 0) {                     // das hier deckt doch die nicht erlaubte division durch 0 ab
            throw new IllegalArgumentException();
        } else if(b == 0) {
            return b;
        }
        return gcd(b, a % b);
    }
 
Schreibe doch einmal eine Matrix auf, wann (a==0 && b == 0) wahr ist. Dann klärt sich auch Dein Kommentar.

Und hast Du verstanden, was "gcd" machen soll? Wofür steht gcd? Und was für ein Algorithmus da implementiert wird? Evtl. sagt Dir Euklid ja durch Zufall etwas ...
Wenn man für irgend eine Problematik Code schreiben will, dann sollte man immer die Problematik und wie diese gelöst werden soll, verstanden haben. Sonst führt es zu einem lustigen Ratespiel... (Zumindest das Gefühl kommt hier gerade bei mir auf.)
 
public int gcd(int a, int b) throws IllegalArgumentException { if(a == 0 && b == 0) { // das hier deckt doch die nicht erlaubte division durch 0 ab throw new IllegalArgumentException(); } else if(b == 0) { return b; } return gcd(b, a % b);
So muss der Algorithmus eigentlich richtig sein , und ja ich weiß was gcd heißt und verstehe auch den Algorithmus dahinter jetzt, deshalb habe ich die neue Zeile hinzugefügt, weil es nur so Sinn macht in der rekursiven Art gcd zu lösen
 
Eine einfache Matrix zu einem Ausdruck wäre etwas in der Art für den Ausdruck in Deinem if
Code:
A     B    Ausdruck
0     0    true
0    !0    false
!0    0    false
!0   !0    false

Und da ist dann direkt klar, dass b==0 auch dahinter möglich ist...

So muss der Algorithmus eigentlich richtig sein
Da ich darauf reagiert habe, wird es wohl nicht so sein.

Wenn Du den Algorithmus kennst, dann wirst Du doch ein paar Testfälle aufstellen können und dazu das richtige Ergebnis sagen können ...
Und dann kannst Du einfach die entsprechenden Aufrufe machen und schauen, ob das richtige Ergebnis raus kommt.
 
Eine einfache Matrix zu einem Ausdruck wäre etwas in der Art für den Ausdruck in Deinem if
Ja gut, wusste nur nicht wie du das richtig meintest mit der Matrix, hatte jetzt grad keine konkrete Vorstellung.
Aber es gibt nur ein Fall in dem es true sein kann, so war das ja im Prinzip gemeint von mir in #17.
Und da ist dann direkt klar, dass b==0 auch dahinter möglich ist...
Sollte man dann zuerst abfragen ob nur b == 0 ist und dann die Abfrage danach ob beide gleichzeitig == 0 sind?
 
Java:
@Override
    public int gcd(int a, int b) throws IllegalArgumentException {
       if(a == 0 && b == 0) {
            throw new IllegalArgumentException();
        } else if(a != 0 && b == 0) {
            return b;
        }
        return gcd(b, a % b);
    }
So würde man abfangen, dass ungleich 0 sein muss wenn b == 0 ist und würde somit vom ersten Fall unterscheiden? Wäre jetzt noch eine Überlegung von mir , was anderes wüsste ich jetzt nicht zu tun...
 
Die Logik ist soweit ok, Du kannst da etwas haben wie:
Java:
public int gcd(int a, int b) throws IllegalArgumentException {
    if(a == 0 && b == 0) {
        throw new ....
    }
    
    if(b == 0) {
        return ....;
    }
        
    return gcd(....);
}

Die Problematik ist nur die Funktionalität und die solltest Du überprüfen. Und dazu brauchst Du uns nicht wirklich. Du machst Dir einfach eine Tabelle wie:
Code:
A    B    gcd(A,B)
0    0
0    1
1    1
1    2
2    1
3    4
6    4
6    9

Wenn Du verstanden hast, was gcd machen soll, dann kannst Du die Spalte mit gcd(A,B) ausfüllen. Da die seine Soll-Liste ist, füllst du die ohne Code auszuführen.

Dann kannst du im Anschluss alles ausführen und schauen, ob deine Implementierung das korrekte Ergebnis liefert.
 
Okay, das stimmt schon. Danke.
Hätte da noch eine Frage:
Java:
public static void main(String[] args) {
        System.out.println(gcd());
        System.out.println(sqrt(25));            //Hier wird mir sqrt rot unterkringelt in Eclipse trotzdessen, dass die Methode korrekt implementiert wurde
        System.out.println(square());
    }
Die Fehlermeldung ist die wie eben: Cannot make a static reference to the non-static method sqrt(int) from the type Maths
Nur habe ich das in #3 nicht wirklich zu beheben verstanden
 
Deine Methode main ist static. Die Methode sqrt ist nicht static. Da main static ist, gibt es in main kein "this" und daher kannst Du keine nicht statischen Methoden aufrufen.
 
1. Okay, danke, wieder dazu gelernt. Was ich mich jetzt noch frage, wie kann ich denn dann jetzt die Methoden in der main testen? Ich kann die Methoden ja nicht static machen, denn die sind ja so vorgegeben worden...
2. Ich will die Klasse jetzt in der cmd ausführen. Mit welchem Tool macht man das nochmal, war das nicht mit dem JavaLauncher?
sprich in der cmd müsste es doch so eingegeben werden: java packagename.Klassenname.java
Das klappt so noch nicht, habe bisher noch nicht herausgefunden was genau ich falsch gemacht habe. Könntest du / oder jemand anderes mir da evtl. es richtig sagen?
3. Ich kann in Eclipse keinen Code mehr schreiben, nichts mit der Leertaste verschieben oder Sonstiges, hat eventuell jemand eine Vorstellung, warum das so ist?
 
Zuletzt bearbeitet:
Okay, danke, wieder dazu gelernt. Was ich mich jetzt noch frage, wie kann ich denn dann jetzt die Methoden in der main testen? Ich kann die Methoden ja nicht static machen, denn die sind ja so vorgegeben worden...
Nicht-statische Methoden sind Methoden, die von Objekten zur Verfügung gestellt werden. Du musst also lediglich ein Objekt Deiner Klasse erzeugen, dann kannst Du dessen Methoden verwenden.

Ich will die Klasse jetzt in der cmd ausführen. Mit welchem Tool macht man das nochmal, war das nicht mit dem JavaLauncher?
sprich in der cmd müsste es doch so eingegeben werden: java packagename.Klassenname.java
Das Build-Tool übersetzt die .java-Datei in Bytecode, der in mindestens einer .class-Datei gespeichert wird. Die .class-Files befindet sich üblicherweise in einem separaten Verzeichnisbaum. Maven legt diese z. B. unter target/classes ab. Darunter findet man dann einen Ordner packagename, in dem sich die Datei Klassenname.class befindet.

Um die Datei auszuführen wechselt man entweder nach target/classes und führt dort java -cp . packagename.Klassenname (ohne .java) aus oder man gibt den Classpath entsprechend an, z. B. aus dem Projektverzeichnis heraus mit java -cp target/classes packagename.Klassenname (ohne .java).

Wenn Du nicht Maven verwendest, musst Du nach dem .class-File suchen.

Ich kann in Eclipse keinen Code mehr schreiben, nichts mit der Leertaste verschieben oder Sonstiges, hat eventuell jemand eine Vorstellung, warum das so ist?
Meine Vorstellung kann ich nicht schreiben, sonst ziehe ich den Zorn des @LimDul auf mich 🙂
 
Wenn Du nicht Maven verwendest, musst Du nach dem .class-File suchen.
Ich verwende kein Maven. Will das mit der ganz normalen Eingabeaufforderung in Windows ausführen.
Gibt ja "javac" zum compilen, "javap" Java Disassembler) um die .class-File zu erzeugen und dann Java um die .class-File entgegenzunehmen und zu interpretieren. Wie suche ich denn jetzt nach der . class-File? Soll ich den Java Disassembler auf packagename.Klassenname anwenden? Und dann den Java Launcher anwenden um den bytecode zu interpretieren und die Hauptklasse zu laden?
Meine Vorstellung kann ich nicht schreiben, sonst ziehe ich den Zorn des @LimDul auf mich
Wie ist das jetzt gemeint? Keine Ahnung was ich daraus lesen soll 😂
 
Will das mit der ganz normalen Eingabeaufforderung in Windows ausführen.
Gibt ja "javac" zum compilen, "javap" Java Disassembler) um die .class-File zu erzeugen und dann Java um die .class-File entgegenzunehmen und zu interpretieren.
Ach so, Du willst alles auf der Kommandozeile machen. Das ist einfach. Du hast ja einen Ordner paketname, in dem sich die Datei Klassenname.java befindet. Wenn Du dich also in dem Ordner befindest, unter dem sich der Ordner paketname befindet, führst Du aus:
Code:
javac paketname/Klassenname.java
java -cp . paketname/Klassenname (ohne .java)

Wie ist das jetzt gemeint? Keine Ahnung was ich daraus lesen soll 😂
Eclipse und mihe7 🙂
 
Das gibt es doch nicht wollte mich anmelden und auf einmal steht dort wieder ein anderer Benutzername, wem muss man da nochmal schreiben um den Fehler beheben zu lassen?
 
Ja, mit der Kommandozeile
Ist der Slash jetzt als oder gemeint oder ist der so einzugeben?
Der Slash ist als Pfadtrenner gemeint. Sollte eigentlich auf jedem System so funktionieren. Unter Windows kannst Du auch den Backslash verwenden.

Das gibt es doch nicht wollte mich anmelden und auf einmal steht dort wieder ein anderer Benutzername, wem muss man da nochmal schreiben um den Fehler beheben zu lassen?
Drück einfach mal bei Deinem Beitrag auf "Report" (unten links), dann kannst Du das ja berichten. Denke mal, dass das bei @mrBrown aufschlägt.
 
Den Account hast du btw seit 2019.
@Flown oder @tbone78 müssten sich drum kümmern, per „Report“ sollte die das auch erreichen.
Ja weiß, dass ich den Account seitdem habe. Habe es per Report gemeldet, warte noch auf Behebung.
@mihe7
javac paketname/Klassenname.java java -cp . paketname/Klassenname (ohne .java)
Das ist grad (nur nebenbei) die Aufgabe konkret:
try to run your class from a command line and report on your approach (working directory, path, command...)
Jetzt war ja hiervon die Rede. Es ist ja eigentlich echt nichts Schweres, nur ein bissche Tüftelei ist es am Anfang jedoch zumindest für mich.
1619273815028.png
javac paketname/Klassenname.java java -cp . paketname/Klassenname (ohne .java)
Das ist mein Paket mit den Klassen, das package widerrum befindet sich in einem Projekt, habe es nur nicht mit ausgeschnitten.
Nach deiner genannten Konvention habe ich es noch nicht hinbekommen. Ist die denn eigentlich übereinstimmten mit der oben genannte Aufgabe bzw. was ist mit working directory genau gemeint?
Was könnte ich falsch gemacht haben?
Habe jetzt erstmal ganz einfach eingegeben: javac assignmentXX/Maths.java, so funktioniert es nur noch nicht...
 
bin jetzt im pfad drin aber komme mit javac packagename/Klassenname.java noch nicht weiter, habe genau deine Konvention befolgt..
Die Klasse ist auch gespeichert daran kanns auch nicht liegen
 
Zuletzt bearbeitet:
Dort steht: "Das System kann den angegebenen Pfad nicht finden.
Habe: cd kopierter Pfad/javac packagename/Klassenname.java und: cd kopierter Pfad javac packagename.Klassenname.java probiert
 
Das System kann den angegebenen Pfad nicht finden.
D. h. dass der Pfad zum bin-Verzeichnis des JDK nicht im PATH ist. Der Fehler kommt auch, wenn Du nur javac eingibst.

Entweder fügst Du den Pfad zur Umgebungsvariable PATH hinzu oder Du gibst den vollständigen Pfad zur javac.exe auf der Kommandozeile mit an.
 
Klappt trotzdem nicht. Habe bemerkt dass ich die jdk 11.0.2 version benutze aber im PATH war die 12.0.2 noch habe den pfad der 12er version jetzt rausgenommen und durch den anderen richtigen ersetzt jedoch funktioniert es immer noch nicht
 
Was hast Du gemacht? Was heißt "funktioniert nicht"? Fehlermeldung? Mensch, lass Dir doch nicht alles aus der Nase ziehen. Wenn Du in der Systemsteuerung die Umgebungsvariable angepasst hast, hast Du die Eingabeaufforderung danach neu geöffnet?
 
Was hast Du gemacht? Was heißt "funktioniert nicht"? Fehlermeldung? Mensch, lass Dir doch nicht alles aus der Nase ziehen. Wenn Du in der Systemsteuerung die Umgebungsvariable angepasst hast, hast Du die Eingabeaufforderung danach neu geöffnet?
Sorry, immer noch diesselbe Fehlermeldung. Und ja, habe die neu geöffnet.
 
Zeig mal einen Screenshot davon wie du javac -version ausführst und danach von den Befehlen die du vorher versucht hast.
 
1619295236602.png

1619295591236.png
Habe den Dokumenten Ordner ausversehen in OneDrive gelegt, ist aber schon länger. Spielt ja aber eigentlich keine Rolle und in dem Zensierten war einfach nur ein Ausdruck in Klammern
 

Zurück
Oben