Umrechnung in verschiedene Zahlensysteme

Karlter

Mitglied
Moin Leute. Ich sitze schon das ganze Wochenende an dieser Aufgabe aber komme einfach nicht weiter. Mittlerweile probiere ich einfach nur noch "blind" herum, was ziemlich frustrierend ist. Es geht um folgende Aufgabenstellung:

Bildschirmfoto 2024-04-28 um 11.34.58.png


Die ersten beiden Methoden konnte ich noch problemlos implementieren, wenn auch etwas "unschön". Das was mir dabei aber so schwer fällt ist zu verstehen, was genau ich denn hier bei der Berechnung jetzt implementieren muss. Ich versuche die ganze Zeit einen Algorithmus zu finden, welcher sich für die Umrechnung aller Zahlensysteme allgemein anwenden lässt, also z.B mit einer Schleife die durch den gegebene String durch iteriert und mit variabler Basis und Potenz arbeitet um dann die neu errechnete Zahl auszugeben. Ist überhaupt möglich hier nur einen einzigen Algorithmus zu verwenden oder muss ich für jede einzelne Umrechnung also z.B Binaer in Dezi, Binaer in Hex, Dezi in Okta oder auch Okta in Binaer eine eigene Methode schreiben, welche ich dann final in convertValue aufrufe?? Aber was dabei für mich dagegen spricht wäre der Kommentar über der letzten Methode, welcher besagt, dass nur diese eine letzte Methode die Berechnung durchführt... Habt ihr eine Lösungsidee zu diesem Problem? Danke für euren Input!! Arrays und OOP sind noch nicht erlaubt!

Das ist mein Code bisher: (die letzte Methode war mein letzter Lösungsansatz, allerdings funktioniert diese nur bei der Berechnung von Binaer in Dezi....)

Java:
import java.util.Scanner;
import static java.lang.System.out;

public class Zahlensysteme {
    

        public static void main(String[] args) {
        
            Scanner scanner = new Scanner(System.in);
            out.print("Zahl: ");
            String str = scanner.next();
            str = str.toLowerCase();
            out.print("Von Zahlensystem (b/d/o/h): ");
            char vonBasis = scanner.next().charAt(0);
            out.print("Zu Zahlensystem (b/d/o/h): ");
            char zuBasis = scanner.next().charAt(0);
            scanner.close();
        
                        
            
        }
        
        
        public static boolean checkValue(String str, int basis) {
            
            boolean gueltig = true;
            
            switch (basis) {
            
            
            case 2:        for(int i = 0; i < str.length(); i++) {
                        
                            if (str.charAt(i) != '0' && str.charAt(i) != '1')
                                gueltig = false;
                            
            
                        }
                        break;
            
            
            case 10:     for(int i = 0; i < str.length(); i++) {
                
                            if (str.charAt(i) < '0' || str.charAt(i) > '9' )
                                gueltig = false;
                        
                        }
                        break;
                        
                        
            case 8:       for(int i = 0; i < str.length(); i++) {
                
                            if (str.charAt(i) < '0' || str.charAt(i) > '7' )
                                gueltig = false;
            
                        }
                        break;
                        
                        
            case 16:      for(int i = 0; i < str.length(); i++) {
                            
                            if ((str.charAt(i) < '0' || str.charAt(i) > '9') && (str.charAt(i) < 'a' || str.charAt(i) > 'f'))
                                gueltig = false;

                        }
                        break;
                        
                        
            default:     gueltig = false;
            
            
            }
            
            return gueltig;

        }
        
        
        public static int convertBasis(char basis) {
            
            switch (basis) {
            
            
            case 'b': return 2;
                        
            case 'o': return 8;
                        
            case 'h': return 16;
            
            case 'd': return 10;
            
            default: return -1;
            
            
            }
            
        }
            
            
            public static String convertValue(String str, int vonBasis, int zuBasis) {
                    
                    
                // ???
                
            }
                
                
            public static int binaerDezi(String str, int Basis) {
                
                int newNumber = 0;
                
                for(int n = 0, i = str.length()-1; i >= 0; i--, n++) {
                    
                    newNumber += (Character.getNumericValue(str.charAt(i))) * Math.pow(Basis, n);
                }
                
                return newNumber;
            }
                
                
            
}
 
Der erste Schritt ist immer gleich: Wie konvertierst DU denn die Zahlen? Oder anders ausgedrückt: Beschreibe doch bitte jemandem, der keine Ahnung von Zahlensystemen hat (aber natürlich einfache Rechnungen machen kann), wie er vorgehen kann?

Ich habe eine Zahl 01001000 im binären System und möchte die Zahl im Hexadezimal-System - wie kannst Du da vorgehen? Bekommst du es mathematisch hin? Du hast ja im Code eine Methode binaerDezi - was genau macht die? (Sieht ein bisschen danach aus, dass da eine Methode, die vom Namen her nur binär in dezimal umwandeln konnte, erweitert wurde ohne den Namen anzupassen) Und dann die Berechnung evtl. umdrehen - also von dezimal zu einem anderen Zahlensystem?

Also nur um es wirklich ganz deutlich zu machen: Es geht hier um keinerlei Code! Es geht hier rein um das fachliche Verständnis, sprich: kennst Du die Mathematik und damit die notwendigen Schritte?

Es ist also wichtig, dass Du den Ablauf im Detail beschreibst - in Worten! Nicht in Code! (Und wenn Du das noch nicht kannst, dann such mal auf Google - du wirst bestimmt viele Seiten dazu finden!)
 
Ohne mir den gesamten code anzusehen fällt schon mal auf.

Einlesen tust du ein Char für den Typ aber deine Methode „checkValue(String str, int basis)“ benutzt ein int

Geht schon mal nicht. Du gibst zb ein ´D´ ein das ist aber kein int 10
 
Ohne mir den gesamten code anzusehen fällt schon mal auf.

Einlesen tust du ein Char für den Typ aber deine Methode „checkValue(String str, int basis)“ benutzt ein int

Geht schon mal nicht. Du gibst zb ein ´D´ ein das ist aber kein int 10

Danke für deinen Hinweis, aber das ist so nicht ganz richtig. Die Übergabeparameter sind ja in der Aufgabenstellung bereits vorgegeben, heißt diese sind fest. Wie du in dem Programmablaufbeispiel aber erkennen kannst, soll ja die Eingabe des Zahlensystems als char erfolgen eben - b, h, o oder d. Ich denke eher, dass im späteren Verlauf dann die Methode convertBasis genutzt wird um die Basis in ein Int umzuwandeln und dann damit die Methode CheckValue aufgerufen wird! Von daher passt das so 🙂
 
Zuletzt bearbeitet:
Der erste Schritt ist immer gleich: Wie konvertierst DU denn die Zahlen? Oder anders ausgedrückt: Beschreibe doch bitte jemandem, der keine Ahnung von Zahlensystemen hat (aber natürlich einfache Rechnungen machen kann), wie er vorgehen kann?

Ich habe eine Zahl 01001000 im binären System und möchte die Zahl im Hexadezimal-System - wie kannst Du da vorgehen? Bekommst du es mathematisch hin? Du hast ja im Code eine Methode binaerDezi - was genau macht die? (Sieht ein bisschen danach aus, dass da eine Methode, die vom Namen her nur binär in dezimal umwandeln konnte, erweitert wurde ohne den Namen anzupassen) Und dann die Berechnung evtl. umdrehen - also von dezimal zu einem anderen Zahlensystem?

Also nur um es wirklich ganz deutlich zu machen: Es geht hier um keinerlei Code! Es geht hier rein um das fachliche Verständnis, sprich: kennst Du die Mathematik und damit die notwendigen Schritte?

Es ist also wichtig, dass Du den Ablauf im Detail beschreibst - in Worten! Nicht in Code! (Und wenn Du das noch nicht kannst, dann such mal auf Google - du wirst bestimmt viele Seiten dazu finden!)

Hallo @KonradN. Danke für deinen Input. Das Umrechnen und das mathematische Fachwissen sind mir realativ klar, aber ich frage mich halt, ob wirklich für jede einzelne Umrechnung eine eigene Methode geschrieben werden muss. Denn z.B. die Umrechnung von Binaer --> Hex (Aufteilung der Bits in 4er Paare) unterscheidet sich ja auch von der Umrechnung von Binaer zum Dezimalsystem. Oder meinst du es wäre dann sinnvoll erstmal jede einzelne Umrechnung auf dem Papier/im Kopf durchzugehen und dann eventuelle Parallelen herauszuarbeiten?
 
nein passt nicht
aber was machst du in der Methode? da musst du auch mit Char weiter arbeiten.

teste es einfach dann wirst du sehen das das nicht geht.
Die convertValue Methode kann ich doch dann später ganz einfach aufrufen mit convertValue(String str, int convertBasis(vonBasis), int convertBasis(zuBasis). Wieso sollte das nicht funktionieren? Das hat ja nichts mit dem Dezimalwert eines Chars zu tuen, denn die Methode convertBasis gibt mir doch die richtige Int Zahl zurück?
 
Danke für deinen Hinweis, aber das ist so nicht ganz richtig. Die Übergabeparameter sind ja in der Aufgabenstellung bereits vorgegeben, heißt diese sind fest. Wie du in dem Programmablaufbeispiel aber erkennen kannst, soll ja die Eingabe des Zahlensystems als char erfolgen eben - b, h, o oder d. Ich denke eher, dass im späteren Verlauf dann die Methode convertBasis genutzt wird um die Basis in ein Int umzuwandeln und dann damit die Methode CheckValue aufgerufen wird! Von daher passt das so 🙂
Da du leider in deine Main Methode noch gar nicht diese Methoden benutzt habe ich die Convert Methode übersehen.
Somit würde das richtig sein. Dann baue das auch immer in der Main zusammen zum Testen.
 
Da du leider in deine Main Methode noch gar nicht diese Methoden benutzt habe ich die Couvert Methode übersehen.
Somit würde das richtig sein. Dann baue das auch immer in der Main zusammen zum Testen.

Achso, ich habe schon an meiner Existenz gezweifelt 😀 Ja beim Testen würde ich das dann über die Main aufrufen, aber so weit bin ich ja noch gar nicht. Ich will ja erstmal herausfinden ob die Umrechnung immer separiert in einer eigenen Methode stattfinden muss, oder ich irgendwie einen Algorithmus finde, welcher dann für alle Zahlensystem gültig ist. Aber ich denke das wird nicht funktionieren. Ich schreibe mir das jetzt einmal auf und schaue mal ob ich eventuell doch etwas finde...
 
Eigentlich hast du es ja schon ich würde die Methode aber anders benennen "stringToInt" das macht sie ja auch.



Für die Ausgabe kannst du ja die Formatierungen von java benutzen.
System.out.printf(" in Hex : %x", deinInt);
 
Hallo @KonradN. Danke für deinen Input. Das Umrechnen und das mathematische Fachwissen sind mir realativ klar, aber ich frage mich halt, ob wirklich für jede einzelne Umrechnung eine eigene Methode geschrieben werden muss. Denn z.B. die Umrechnung von Binaer --> Hex (Aufteilung der Bits in 4er Paare) unterscheidet sich ja auch von der Umrechnung von Binaer zum Dezimalsystem. Oder meinst du es wäre dann sinnvoll erstmal jede einzelne Umrechnung auf dem Papier/im Kopf durchzugehen und dann eventuelle Parallelen herauszuarbeiten?
Kannst Du das nicht allgemein ausdrücken?

Du kannst Dir ja mal überlegen, wie es funktioniert, wenn Du Variablen hast.

Du hast also eine Zahl mit den Ziffern xyz zur Basis B.

Kannst Du den Wert im 10er System berechnen?

Und wenn Du die Zahl Z im Zehnersystem hast und sollst diese zur Basis B ausdrücken: Kannst Du das auch mathematisch (oder in Form eines Vorgehens) beschreiben?

Dann bräuchtest Du nur noch jeweils eine Methode.

Aber hier gibt es auch noch eine andere Herangehensweise:
Du kannst auch einfach hin gehen und den Algorithmus beschreiben. Dann entwirfst Du erst einen Algorithmus z.B. für die Umwandlung von binär -> dezimal. Und dann für oktal -> dezimal.
Und dann kannst Du schauen, in wie weit sich diese unterscheiden oder ob man die zusammen fassen könnte.
(Das ist übrigens oft der Ansatz in der Entwicklung. Man schreibt erst eine Methode, die z.B. nur binär nach dezimal umwandeln kann und dann erweitert man es. Das aber nur als einfache Information - im Augenblick dürfte es für Dich uninteressant sein. Stichwort wäre hier unter anderem Test Driven Development TDD.)
 
Solltest du bis jetzt noch nicht drauf gekommen sein einen INT in einen String zu wandeln eine einfache form hier.
Java:
 static String integerToSting(int input, int basis) {
        String digits = "0123456789ABCDEF";
        if (input <= 0)
            return "0";
        StringBuilder str = new StringBuilder();
        while (input > 0) {
            int digit = input % basis;
            str.insert(0, digits.charAt(digit));
            input = input / basis;
        }
        return str.toString();
    }
 
Solltest du bis jetzt noch nicht drauf gekommen sein einen INT in einen String zu wandeln eine einfache form hier.
Java:
 static String integerToSting(int input, int basis) {
        String digits = "0123456789ABCDEF";
        if (input <= 0)
            return "0";
        StringBuilder str = new StringBuilder();
        while (input > 0) {
            int digit = input % basis;
            str.insert(0, digits.charAt(digit));
            input = input / basis;
        }
        return str.toString();
    }

Danke, aber ich würde die Aufgabe gerne so lösen wie es die Aufgabenstellung verlangt - Wir dürfen leider keinen StringBuilder nutzen... Ich habe jetzt zumindest mal eine Methode geschrieben welche eine beliebige Zahl aus einen variablen Zahlensystem in eine Dezimalzahl umrechnet:

Java:
public static int toDezi(String str, int Basis) {
                
            int n = 0;
            int dezimal = 0;
            
            for(int i = str.length()-1; i >= 0;) {
                
                if(i == 'a') {
                    
                    dezimal += (int) 10 * Math.pow(Basis, n);
                    
                } else if (i == 'b') {
                    
                    dezimal += (int) 11 * Math.pow(Basis, n);
                    
                } else if (i == 'c') {
                    
                    dezimal += (int) 12 * Math.pow(Basis, n);
                    
                } else if (i == 'd') {
                    
                    dezimal += (int) 13 * Math.pow(Basis, n);
                    
                } else if (i == 'e') {
                    
                    dezimal += (int) 14 * Math.pow(Basis, n);
                    
                } else if (i == 'f') {
                        
                    dezimal += (int) 15 * Math.pow(Basis, n);
                        
                } else {
            
                dezimal += (int) (Character.getNumericValue(str.charAt(i)) * Math.pow(Basis, n));
                n++;
                i--;
                
                }
            
            }
            
            return dezimal;
            
        }


Jetzt versuche ich das ganze mal umzudrehen und mit Modulo zu lösen, dann sollte die Umrechnung zwischen Dezimal und den anderen Systemen schon mal klappen. Danke @KonradN!
 
Den Code hast Du bestimmt nicht (richtig) getestet.

Direkt der Tipp als erstes: Wenn Du eine Zählschleife machst, dann erhöhst Du bitte den Zähler nur in dem Schleifenkopf!

Die Fehler:
a) i ist bei Dir die Position im String. Du willst aber doch nicht die Position prüfen sondern das Zeichen an der Stelle.
b) Und wenn du eine Zahl umwandelst mit einer Ziffer von a - f, dann hast Du in Deinem Code eine Endlosschleife (So Du a) verbessert hast. In der aktuellen Form wäre es z.B. bei einer binären Zahl mit mehr als 10 Stellen...)

Bezüglich den vielen if Abfragen - die kannst Du natürlich in einer Abfrage machen. Da ein Zeichen auch nur eine Zahl ist, kannst Du da einen Bereich abprüfen bezüglich >= 'a' && <= 'f'. Und der gesuchte Wert ist dann das Zeichen - 'a' + 10.
 
Java:
public static int toDezi(String str, int Basis) {
             
            int n = 0;
            int dezimal = 0;
         
            for(int i = str.length()-1; i >= 0; i--) {
             
                if(str.charAt(i) == 'a') {
                 
                    dezimal += (int) 10 * Math.pow(Basis, n);
                 
                } else if (str.charAt(i) == 'b') {
                 
                    dezimal += (int) 11 * Math.pow(Basis, n);
                 
                } else if (str.charAt(i) == 'c') {
                 
                    dezimal += (int) 12 * Math.pow(Basis, n);
                 
                } else if (str.charAt(n) == 'd') {
                 
                    dezimal += (int) 13 * Math.pow(Basis, n);
                 
                } else if (str.charAt(n) == 'e') {
                 
                    dezimal += (int) 14 * Math.pow(Basis, n);
                 
                } else if (str.charAt(n) == 'f') {
                     
                    dezimal += (int) 15 * Math.pow(Basis, n);
                     
                } else {
         
                dezimal += (int) (Character.getNumericValue(str.charAt(i)) * Math.pow(Basis, n));
                n++;
             
                }
         
            }
         
            return dezimal;
         
        }


Danke für den Hinweis @KonradN 🙂 So sollte das dann wohl besser passen, allerdings verstehe ich nicht was du mit den zusammenfassen der If-Abfragen meinst? Klar, ich kann den Bereich eingrenzen auf a-f, aber woher soll er dann wissen, dass bei 'a' mit Wert 10, bei 'b' mit 11 usw. multipliziert wird? Oder wo liegt mein Denkfehler? Dann bräuchte ich ja dort auch wieder eine eigene Fallunterscheidung zwischen den einzelnen Zeichen oder nicht?
 
Zuletzt bearbeitet:
Java:
public static int toDezi(String str, int Basis) {
            
            int n = 0;
            int dezimal = 0;
        
            for(int i = str.length()-1; i >= 0; i--) {
            
                if(str.charAt(i) >= 'a' && str.charAt(i) <= 'f') {                 
                    dezimal += (int) (str.charAt(i) - 'a' + 10) * Math.pow(Basis, n);                 
                } else {
                    dezimal += (int) (Character.getNumericValue(str.charAt(i)) * Math.pow(Basis, n));
                }
                n++;
            }
    
            return dezimal;
        }

Zum einen siehst Du, was ich mit der Zusammenfassung meinte.
Und zum anderen ist noch ein Fehler bezüglich der Erhöhung von n beseitigt! (n muss nach jeder Ziffer erhöht werden!)

Prinzipiell würde ich auf Math.pow verzichten und statt n eine Variable Basis einführen. Diese wird auf 1 initialisiert und nach jeder Ziffer mit Basis multipliziert. Das dürfte günstiger sein als die Math.pow Berechnungen.
 
Meinst du so?:

Java:
public static int toDezi(String str, int Basis) {
              
            int b = 1;
            int dezimal = 0;
          
            for(int i = str.length()-1; i >= 0; i--) {
              
                if(str.charAt(i) >= 'a' && str.charAt(i) <= 'f') { 
                  
                    dezimal += (int) (str.charAt(i) - 'a' + 10) * b;
                      
                } else {
          
                    dezimal += (int) (Character.getNumericValue(str.charAt(i)) * b);
          
                }
              
                b = b * Basis;
          
            }
          
            return dezimal;
          
        }


Da wäre ich so gar nicht drauf gekommen... Jetzt verstehe ich das wie du das meinst mit der Berechnung des Wertes des einzelnen Zeichen. Siehst du sowas eigentlich direkt intuitiv oder ist das einfach die Erfahrung die du hast @KonradN? Ich kann das zwar nachvollziehen und es ist ja im Grunde auch nur einfache Mathematik, aber direkt zu sehen, dass man das hätte so vereinfacht schreiben können... damit tue ich mir noch etwas schwer 🙁
 
Berechnung des Wertes des einzelnen Zeichen. Siehst du sowas eigentlich direkt intuitiv oder ist das einfach die Erfahrung die du hast @KonradN?
Also mal davon abgesehen, dass jede zweite Frage hier im Forum sich damit auseinander setzt, ist es so, dass man als Programmierer ein gewisses level an Abstraktion benötigt...
Man erstellt Algorithmus, der eine KLasse von Probelemen lösen soll... Wenn ich addieren will, dann mache ich ja nicht

if (1. Summand == 1) und (2. Summand == 2) return 2

Sondern return summand1 + summand2;

Gruß,
Martin
 
Software Entwicklung ist etwas, das sehr viel mit Erfahrung zu tun hat. Daher sagt man oft auch: Programmieren lernt man nur durch programmieren. Und mit der Erfahrung kommt dann automatisch, dass man sehr vieles direkt sieht.

Hier ist es aber dann auch so, dass dies eine 08/15 Aufgabenstellung ist, die man bereits in Schule und Studium hatte und die auch öfters im Forum aufschlägt.
 
Wirklich vielen Dank für Eure Unterstützung! Ich hoffe, dass ich da irgendwann auch nochmal hinkomme 😀 Hier übrigens mein finaler Code, bis jetzt funktionieren alle Testfälle. Ich habe es jetzt einfach so gelöst, dass ich immer erst in eine Dezimalzahl umrechne und dann in das verlangte finale Zahlensystem... fällt euch noch irgendwas schwerwiegendes auf?

Java:
import java.util.Scanner;
import static java.lang.System.out;

public class Zahlensysteme {
  

        public static void main(String[] args) {
      
            Scanner scanner = new Scanner(System.in);
            out.print("Zahl: ");
            String str = scanner.next();
            str = str.toLowerCase();
            out.print("Von Zahlensystem (b/d/o/h): ");
            char vonBasis = scanner.next().charAt(0);
            out.print("Zu Zahlensystem (b/d/o/h): ");
            char zuBasis = scanner.next().charAt(0);
            scanner.close();
            out.println();
          
            if (checkValue(str, convertBasis(vonBasis)) == false || convertBasis(vonBasis) == -1 || convertBasis(zuBasis) == -1)
                System.out.printf("%s von Basis %d nach Basis %d = Falsche Eingabe", str, convertBasis(vonBasis), convertBasis(zuBasis));
            else
                System.out.printf("%s von Basis %d nach Basis %d = %s", str, convertBasis(vonBasis), convertBasis(zuBasis), convertValue(str, convertBasis(vonBasis), convertBasis(zuBasis)));
                      
          
        }
      
      
        public static boolean checkValue(String str, int basis) {
          
            boolean gueltig = true;
          
            switch (basis) {
          
          
            case 2:        for(int i = 0; i < str.length(); i++) {
                      
                            if (str.charAt(i) != '0' && str.charAt(i) != '1')
                                gueltig = false;
                          
                        }
                        break;
          
          
            case 10:     for(int i = 0; i < str.length(); i++) {
              
                            if (str.charAt(i) < '0' || str.charAt(i) > '9' )
                                gueltig = false;
                      
                        }
                        break;
                      
                      
            case 8:       for(int i = 0; i < str.length(); i++) {
              
                            if (str.charAt(i) < '0' || str.charAt(i) > '7' )
                                gueltig = false;
          
                        }
                        break;
                      
                      
            case 16:      for(int i = 0; i < str.length(); i++) {
                          
                            if ((str.charAt(i) < '0' || str.charAt(i) > '9') && (str.charAt(i) < 'a' || str.charAt(i) > 'f'))
                                gueltig = false;

                        }
                        break;
                      
                      
            default:     gueltig = false;
          
          
            }
          
            return gueltig;

        }
      
      
      
        public static int convertBasis(char basis) {
          
            switch (basis) {
          
          
            case 'b': return 2;
                      
            case 'o': return 8;
                      
            case 'h': return 16;
          
            case 'd': return 10;
          
            default: return -1;
          
          
            }
          
        }
      
          
          
        public static String convertValue(String str, int vonBasis, int zuBasis) {
          
            String finalstr = fromDezi(toDezi(str, vonBasis), zuBasis);
                      
            return finalstr; 
          
        }
              
          
      
        public static int toDezi(String str, int Basis) {
              
            int b = 1;
            int dezimal = 0;
          
            for(int i = str.length()-1; i >= 0; i--) {
              
                if(str.charAt(i) >= 'a' && str.charAt(i) <= 'f') { 
                  
                    dezimal += (int) (str.charAt(i) - 'a' + 10) * b;
                      
                } else {
          
                    dezimal += (int) (Character.getNumericValue(str.charAt(i)) * b);
          
                }
              
                b = b * Basis;
          
            }
          
            return dezimal;
          
        }
      
      
      
        public static String fromDezi(int dezi, int basis) {
          
            String str = "";
            String strnew = "";
          
            do {
              
                if((dezi % basis) > 9) {
                  
                  
                    switch (dezi % basis) {
                  
                    case 10: str += 'a';
                             break;
                  
                    case 11: str += 'b';
                             break;
                  
                    case 12: str += 'c';
                             break;
                  
                    case 13: str += 'd';
                             break;
                  
                    case 14: str += 'e';
                             break;
                  
                    case 15: str += 'f';
                             break;
                  
                    }
                  
                    dezi = dezi / basis;
                  
                } else {
              
                    str += dezi % basis;
                    dezi = dezi / basis;
              
                }
              
            } while (dezi != 0);
          
          
            for(int i = str.length()-1; i >= 0; i--) {
              
                strnew += str.charAt(i);
              
            }
          
            return strnew;
          
        }
  
  
}
 
Ich habe es jetzt einfach so gelöst, dass ich immer erst in eine Dezimalzahl umrechne und dann in das verlangte finale Zahlensystem
Das ist aus meiner Sicht auch das richtige Vorgehen. Wenn man etwas programmiert, dann ist es wichtig, dass man es möglichst für Menschen lesbar hält. Und ein Grundsatz dabei ist "KISS" - Keep It Simple, Stupid.
Ein sehr wichtiges Vorgehen bei der Software Entwicklung nennt sich "divide and conquer" - teile und herrsche. Du unterteilst also Probleme immer in kleinere Teilprobleme, die dann entweder weiter unterteilt werden oder die dann so klein sind, dass sie einfach lösbar sind.

Evtl. ein paar kleine Anmerkungen:

  • Du hast ein if switch else Aufbau und im switch hast Du kein default. Das if kannst Du also auch weg lassen und einfach den Code vom else dann im default Block vorhalten Oder:
  • Statt dem Switch hast Du ein einfaches if / else - und den Buchstaben ermittelst Du per 'a' - 10 + ziffer.
  • Statt die Ziffern immer rechts anzuhängen und dann den String umzudrehen kannst Du die Ziffer auch links anfügen. Also statt str += ziffer ein str = ziffer + str

Der Code sieht aber - auf den ersten Blick - gut aus und die Bemerkungen wären aus meiner Sicht alles nur "nice to have" Dinge.
 
Ich verstehe denn Aufwand nicht den du betreibst.
Du hattest doch im ersten Post eine Methode die genau einen String in einen int wandelt. Nur der nahme fande Konrad und auch ich nicht sinnvoll.
Die Methode macbte genau das was sue solte und zwar für alle Zahlensysteme
2, 8, 10,16 du hast ja auch die basis mit angegeben.

Das was du woltest eine Methode für alle systeme hattest du doch.

Was von der Methode darfst du noch nucht benutzen?

Character.getNumericValue kannst du dir such selber basteln.
Dann schaue dir mal die ASCII Tabelle an.

Auch Potenz kann mann sich selber bauen. Wenn es noch nicht erlaubt ist.


Und zu meinen Code wandeln eis int in ein anderes Dateisystem als String.
Wenn du da StringBuilder noch nicht benuten darfst. Dann schsue dir doch mal den pulus "+" Operator für Strings an.
Damit kann mann Strings verbinden.
 
ohne StringBuilder
Java:
static String integerToSting(int input, int basis) {
        String digits = "0123456789ABCDEF";
        if (input <= 0)
            return "0";
        String  str = "";
        while (input > 0) {
            int digit = input % basis;
            str = String.valueOf(digits.charAt(digit)) + str;
            input = input / basis;
        }
        return str;
    }
 
Ich verstehe denn Aufwand nicht den du betreibst.
Er hat eigenständig eine Lösung erarbeitet. Das ist aus meiner Sicht deutlich besser, als eine Lösung, die ihm hingeworfen wird, zu verwenden. Ich finde das sehr gut (und das Geben von fertigen Lösungen finde ich weniger gut, vor allem wenn es in der Form "Friss oder stirb" einfach hingeworfen wird ohne jede Erklärung).

Sinn der Aufgaben ist doch nicht, dass die Schüler da einen Algorithmus entwickeln, den sie später ständig brauchen sondern um ein üben, dass man von einer Problemstellung hin zu einer Lösung kommt. Meine bescheidenden Meinung nach ist daher auch genau das die Hilfe, die wir geben sollten.

Das einfach nur kurz als meine Sicht. Daher: @Karlter - alles richtig gemacht!
 
Später sollten seine Lösungen aber vor allem richtig sein. Das ist eine der Grundvoraussetzungen. Egal, mit welchem didaktischen Ansatz gelernt wurde.

Oder heißt es dann, ok deine Lösung funktioniert zwar nicht und ist unbrauchbar, aber du hast dich ja sehr bemüht und der Weg ist ja das Ziel?
 
Später sollten seine Lösungen aber vor allem richtig sein. Das ist eine der Grundvoraussetzungen. Egal, mit welchem didaktischen Ansatz gelernt wurde.

Oder heißt es dann, ok deine Lösung funktioniert zwar nicht und ist unbrauchbar, aber du hast dich ja sehr bemüht und der Weg ist ja das Ziel?
Damit unterstellst Du doch, dass die Lösung vom TE nicht korrekt ist. Dann solltest Du klar sagen, was für Probleme du siehst. Ansonsten ist es nicht hilfreich.
 
import java.util.Scanner;
import static java.lang.System.out;

-> out wird nicht importiert

public class Zahlensysteme {


public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

-> Scanner?

out.print("Zahl: ");
String str = scanner.next();
str = str.toLowerCase();
out.print("Von Zahlensystem (b/d/o/h): ");

-> die Reihenfolge stimmt nicht

char vonBasis = scanner.next().charAt(0);
out.print("Zu Zahlensystem (b/d/o/h): ");

-> die Reihenfolge stimmt nicht

char zuBasis = scanner.next().charAt(0);
scanner.close();
out.println();

if (checkValue(str, convertBasis(vonBasis)) == false || convertBasis(vonBasis) == -1 || convertBasis(zuBasis) == -1)
System.out.printf("%s von Basis %d nach Basis %d = Falsche Eingabe", str, convertBasis(vonBasis), convertBasis(zuBasis));
else
System.out.printf("%s von Basis %d nach Basis %d = %s", str, convertBasis(vonBasis), convertBasis(zuBasis), convertValue(str, convertBasis(vonBasis), convertBasis(zuBasis)));

-> { } fehlen
-> == false vermeiden
-> == -1 vermeiden
-> Zwischenvariablen verwenden


}


public static boolean checkValue(String str, int basis) {

boolean gueltig = true;

switch (basis) {


case 2: for(int i = 0; i < str.length(); i++) {

if (str.charAt(i) != '0' && str.charAt(i) != '1')
gueltig = false;

-> { } fehlen

}
break;


case 10: for(int i = 0; i < str.length(); i++) {

if (str.charAt(i) < '0' || str.charAt(i) > '9' )
gueltig = false;

-> { } fehlen

}
break;


case 8: for(int i = 0; i < str.length(); i++) {

if (str.charAt(i) < '0' || str.charAt(i) > '7' )
gueltig = false;

-> { } fehlen

}
break;


case 16: for(int i = 0; i < str.length(); i++) {

if ((str.charAt(i) < '0' || str.charAt(i) > '9') && (str.charAt(i) < 'a' || str.charAt(i) > 'f'))
gueltig = false;

-> { } fehlen

}
break;


default: gueltig = false;

-> Logik kann umgedreht werden


}

return gueltig;

}



public static int convertBasis(char basis) {

switch (basis) {


case 'b': return 2;

case 'o': return 8;

case 'h': return 16;

case 'd': return 10;

default: return -1;

-> die Reihenfolge stimmt nicht
-> default ist überflüssig
-> zu kompliziert, kann vereinfacht werden -> Array


}

}



public static String convertValue(String str, int vonBasis, int zuBasis) {

String finalstr = fromDezi(toDezi(str, vonBasis), zuBasis);

return finalstr;

-> Inlinen

}



public static int toDezi(String str, int Basis) {

int b = 1;
int dezimal = 0;

for(int i = str.length()-1; i >= 0; i--) {

if(str.charAt(i) >= 'a' && str.charAt(i) <= 'f') {

dezimal += (int) (str.charAt(i) - 'a' + 10) * b;

} else {

dezimal += (int) (Character.getNumericValue(str.charAt(i)) * b);

}

b = b * Basis;

-> "*=" verwenden

}

return dezimal;

}



public static String fromDezi(int dezi, int basis) {

String str = "";
String strnew = "";

-> strNew

do {

if((dezi % basis) > 9) {


switch (dezi % basis) {

case 10: str += 'a';
break;

case 11: str += 'b';
break;

case 12: str += 'c';
break;

case 13: str += 'd';
break;

case 14: str += 'e';
break;

case 15: str += 'f';
break;

}

-> kann vereinfacht werden

dezi = dezi / basis;

-> "/=" verwenden

} else {

str += dezi % basis;
dezi = dezi / basis;

-> "/=" verwenden

}

} while (dezi != 0);


for(int i = str.length()-1; i >= 0; i--) {

strnew += str.charAt(i);

}

-> rückwärts laufende Schleife

return strnew;

}


}

Das sind schon 23 Fehler nach einem Schnelldurchlauf.
 
Damit unterstellst Du doch, dass die Lösung vom TE nicht korrekt ist. Dann solltest Du klar sagen, was für Probleme du siehst. Ansonsten ist es nicht hilfreich.

Genau das Gleiche habe ich mir auch gerade gedacht...

import java.util.Scanner;
import static java.lang.System.out;

-> out wird nicht importiert

public class Zahlensysteme {


public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

-> Scanner?

out.print("Zahl: ");
String str = scanner.next();
str = str.toLowerCase();
out.print("Von Zahlensystem (b/d/o/h): ");

-> die Reihenfolge stimmt nicht

char vonBasis = scanner.next().charAt(0);
out.print("Zu Zahlensystem (b/d/o/h): ");

-> die Reihenfolge stimmt nicht

char zuBasis = scanner.next().charAt(0);
scanner.close();
out.println();

if (checkValue(str, convertBasis(vonBasis)) == false || convertBasis(vonBasis) == -1 || convertBasis(zuBasis) == -1)
System.out.printf("%s von Basis %d nach Basis %d = Falsche Eingabe", str, convertBasis(vonBasis), convertBasis(zuBasis));
else
System.out.printf("%s von Basis %d nach Basis %d = %s", str, convertBasis(vonBasis), convertBasis(zuBasis), convertValue(str, convertBasis(vonBasis), convertBasis(zuBasis)));

-> { } fehlen
-> == false vermeiden
-> == -1 vermeiden
-> Zwischenvariablen verwenden


}


public static boolean checkValue(String str, int basis) {

boolean gueltig = true;

switch (basis) {


case 2: for(int i = 0; i < str.length(); i++) {

if (str.charAt(i) != '0' && str.charAt(i) != '1')
gueltig = false;

-> { } fehlen

}
break;


case 10: for(int i = 0; i < str.length(); i++) {

if (str.charAt(i) < '0' || str.charAt(i) > '9' )
gueltig = false;

-> { } fehlen

}
break;


case 8: for(int i = 0; i < str.length(); i++) {

if (str.charAt(i) < '0' || str.charAt(i) > '7' )
gueltig = false;

-> { } fehlen

}
break;


case 16: for(int i = 0; i < str.length(); i++) {

if ((str.charAt(i) < '0' || str.charAt(i) > '9') && (str.charAt(i) < 'a' || str.charAt(i) > 'f'))
gueltig = false;

-> { } fehlen

}
break;


default: gueltig = false;

-> Logik kann umgedreht werden


}

return gueltig;

}



public static int convertBasis(char basis) {

switch (basis) {


case 'b': return 2;

case 'o': return 8;

case 'h': return 16;

case 'd': return 10;

default: return -1;

-> die Reihenfolge stimmt nicht
-> default ist überflüssig
-> zu kompliziert, kann vereinfacht werden -> Array


}

}



public static String convertValue(String str, int vonBasis, int zuBasis) {

String finalstr = fromDezi(toDezi(str, vonBasis), zuBasis);

return finalstr;

-> Inlinen

}



public static int toDezi(String str, int Basis) {

int b = 1;
int dezimal = 0;

for(int i = str.length()-1; i >= 0; i--) {

if(str.charAt(i) >= 'a' && str.charAt(i) <= 'f') {

dezimal += (int) (str.charAt(i) - 'a' + 10) * b;

} else {

dezimal += (int) (Character.getNumericValue(str.charAt(i)) * b);

}

b = b * Basis;

-> "*=" verwenden

}

return dezimal;

}



public static String fromDezi(int dezi, int basis) {

String str = "";
String strnew = "";

-> strNew

do {

if((dezi % basis) > 9) {


switch (dezi % basis) {

case 10: str += 'a';
break;

case 11: str += 'b';
break;

case 12: str += 'c';
break;

case 13: str += 'd';
break;

case 14: str += 'e';
break;

case 15: str += 'f';
break;

}

-> kann vereinfacht werden

dezi = dezi / basis;

-> "/=" verwenden

} else {

str += dezi % basis;
dezi = dezi / basis;

-> "/=" verwenden

}

} while (dezi != 0);


for(int i = str.length()-1; i >= 0; i--) {

strnew += str.charAt(i);

}

-> rückwärts laufende Schleife

return strnew;

}


}

Das sind schon 23 Fehler nach einem Schnelldurchlauf.

Und genau an deinem Beitrag erkennt man, dass du nicht verstehst wovon @KonradN hier redet. Als Anfänger ist es viel hilfreicher, wenn man jemanden hat, der einen hilft, erstmal nur den Weg zu finden, wie man eine Lösung entwickelt. Genau das hat er getan und das hat am Ende auch dazu geführt, dass ich ein semantisch "größtenteils" korrektes Programm implementiert habe. Natürlich mache ich noch viele Fehler, mal abgesehen davon, dass man meines Wissens nach If-else Anweisungen sehr wohl ohne Klammern schreiben kann (soweit nur eine Anweisung folgt), die Reihenfolge so ist wie in dem Beispiel vorgegeben und mir deine "gravierenden" Fehler jetzt nicht all zu schlimm erscheinen. Du hast dir meinen Post anscheinend auch nichtmal richtig durchgelesen, denn dort sage ich bereits, dass ich z.B keine Arrays verwenden darf 😀 Ich bin erstmal stolz, dass der Code funktioniert... Schönheitskorrektur kann man immer noch danach machen. Ich bin ein ANFÄNGER und solche Kommentare, genau wie z.B die von @Jw456 sind weder konstruktiv, noch hilfreich. Mir scheint es so, als ob ihr beide zwar ein umfangreiches Fachwissen besitzt, aber die pädagogische Kompetenz dann doch eher zu wünschen übrig lässt. Kritik ist wichtig, aber auch nur wenn diese richtig formuliert wird. Ansonsten sollte man sich sie sparen 😉 Danke @KonradN! Ich setze mich nun an die nächste Aufgabe 🙂
 
Zuletzt bearbeitet:
Ok, dann gehen wir die einzelnen Punkte einmal durch:
import static java.lang.System.out;

-> out wird nicht importiert
Es ist technisch ok. Es ist unüblich und ich würde es in einem Code Review auch anmeckern, aber es ist erst einmal nicht für die Aufgabe interessant. Ursache wird hier evtl. sogar ein "Der Lehrer hat es so vorgemacht" sein, wobei ich nicht ausschließen möchte, dass es evtl. auch beim Schreiben ein Tippfehler war und eine IDE dann den static import als quick fix vorgeschlagen hat.

Ursache ist aber egal - für die Funktionalität ist es uninteressant. Wenn einen sowas stört, dann kann man es erläutern.

Scanner scanner = new Scanner(System.in);

-> Scanner?
Was spricht gegen die Nutzung des Scanners? Wird in vielen Klassen als einfache Möglichkeit für Eingaben genutzt. So vermutlich auch hier. Was ist die Alternative? Die deutlich komplexeren Streams?

out.print("Von Zahlensystem (b/d/o/h): ");

-> die Reihenfolge stimmt nicht
Das ist die Reihenfolge, die in der Aufgabe genannt wurde. Wer sagt denn, dass die Anzahl der Bytes die natürliche Ordnung ist, die genommen werden muss?

if (checkValue(str, convertBasis(vonBasis)) == false || convertBasis(vonBasis) == -1 || convertBasis(zuBasis) == -1)
System.out.printf("%s von Basis %d nach Basis %d = Falsche Eingabe", str, convertBasis(vonBasis), convertBasis(zuBasis));
else
System.out.printf("%s von Basis %d nach Basis %d = %s", str, convertBasis(vonBasis), convertBasis(zuBasis), convertValue(str, convertBasis(vonBasis), convertBasis(zuBasis)));

-> { } fehlen
-> == false vermeiden
-> == -1 vermeiden
-> Zwischenvariablen verwenden
Das sind Dinge, die man aus Clean Code Sicht machen kann (bzw. sollte). Aber erneut: Clean Code != Funktionalität. Du meckerst die Funktionalität an statt einfach nur die Punkte freundlich zu erläutern.

-> Logik kann umgedreht werden
Macht aber für die Funktionalität keinen Unterschied.
-> die Reihenfolge stimmt nicht
-> default ist überflüssig
-> zu kompliziert, kann vereinfacht werden -> Array
default ist nicht überflüssig - nur da hätte ich eher eine Exception geworfen oder dafür eher eine Enumeration verwendet oder oder oder ... Ist aber egal, da dies alles nicht erwünscht ist:
Danke für euren Input!! Arrays und OOP sind noch nicht erlaubt!
Daher würde die Umsetzung Deiner Idee de fakto zu einer falschen Lösung führen, weil die Anforderungen nicht erfüllt sind.
String finalstr = fromDezi(toDezi(str, vonBasis), zuBasis);

return finalstr;

-> Inlinen
Wie schon vorher auch: Das ist wirklich nur ein minimaler Clean Code Punkt. Wird vermutlich von dem Compiler optimiert. Funktionell kein Thema.

b = b * Basis;

-> "*=" verwenden
Also das finde ich teilweise nicht einmal gut. Diese verkürzten Schreibweisen sind teilweise beim schnellen überfliegen von Code schlechter lesbar als das ausgeschriebene. Aber das ist nur meine Meinung. Als Clean Code Vorgabe ist es mir bisher nicht unter gekommen.

for(int i = str.length()-1; i >= 0; i--) {

strnew += str.charAt(i);

}

-> rückwärts laufende Schleife
Wo ist das ein Problem in Deinen Augen?

Das sind schon 23 Fehler nach einem Schnelldurchlauf.
Sorry, aber es sind keine Fehler sondern lediglich Clean Code Hinweise. Sorry Tobias, aber hier geht es um ein einfaches Anfänger-Thema. Da mit diesen Clean Code Vorgaben ist Quatsch. Spätestens bei den Fällen, wo die Anforderung diese explizit ausschließt wäre die Verbessrung der Lösung etwas, das die Lösung verschlechtern würde.

Wenn man so großen Wert auf soPunkte legt, dann kann man da freundlich darauf hin weisen. Aber dann bitte auch mit kurzer Erläuterung.

Eine Aussage wie
Später sollten seine Lösungen aber vor allem richtig sein. Das ist eine der Grundvoraussetzungen. Egal, mit welchem didaktischen Ansatz gelernt wurde.

Oder heißt es dann, ok deine Lösung funktioniert zwar nicht und ist unbrauchbar, aber du hast dich ja sehr bemüht und der Weg ist ja das Ziel?
ist in meinen Augen schlicht nicht akzeptabel.
 
Dein Code ist der letzte Müll. Mehr kann man dazu nicht sagen. Und wenn du in einem Forum nach Hilfe fragst, dann sind wir nicht dafür da um Händchen zu halten.
Anfänger sind im Forum willkommen und es gibt genug Leute, die denen Helfen wollen. Wenn Du das nicht willst, dann halte Dich aus den entsprechenden Threads raus. Wenn Du möchtest, dann kannst Du auch gerne auf Clean Code Punkte hinweisen, aber solche Antworten (Edit: Wie Du hier in #33 und vorher etwas in #28 gebracht hast) sind aus meiner Sicht schlicht nicht willkommen. Verhalte Dich daher bitte entsprechend.

Edit: Missverständliches "solche Antworten" - Hinweise auf Clean Code sind natürlich willkommen. Es bezog sich die vorherigen Posts.
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben