Zahldarstellung zur Basis 2,4,8 und 10

Guest1

Aktives Mitglied
Screenshot_20181204-211251_Gallery.jpg Hallo,
Ich soll ein paar Methoden realisieren die mir Zahlen addiert.
Die Zahlen sollen in verschiedenen Basen
angezeigt werden (2,4,8, 10).
Außerdem soll ich die Aufgabe nur mit einfacher Rekursion lösen.(mit arithmetischen Operatoren, mit Rekursion ohne Schleifen und String Operationen)

So habe ich angefangen:

public static long addiere( long zahl1, long zahl2, int basis){
return basis == 10
? zahl1 + zahl2
:

MfG
 
Zuletzt bearbeitet:

httpdigest

Top Contributor
Naja, wenn du die Zahlen schon als long Werte hast - die ja von einer Formatierung der repräsentierten Zahl erstmal völlig unabhängig sind - kannst du sie ja einfach addieren (egal, zu welcher Basis) und dann das Ergebnis irgendwann mal zu einer Basis interpretiert als String ausgeben.
Ein long-Wert alleine besitzt keine Basis an sich. Die Basis spielt nur eine Rolle beim Parsen eines Strings in einen long oder beim Formatieren eines longs als String.
Ich denke eher, dass du die Zahlen als String (interpretiert in einer gegebenen Basis) einlesen sollst, dann normal eine arithmetische Operation ausführen sollst, und dann das Ergebnis wieder in die Zielbasis interpretiert als String ausgeben sollst.
 

Guest1

Aktives Mitglied
Naja, wenn du die Zahlen schon als long Werte hast - die ja von einer Formatierung der repräsentierten Zahl erstmal völlig unabhängig sind - kannst du sie ja einfach addieren (egal, zu welcher Basis) und dann das Ergebnis irgendwann mal zu einer Basis interpretiert als String ausgeben.
Ein long-Wert alleine besitzt keine Basis an sich. Die Basis spielt nur eine Rolle beim Parsen eines Strings in einen long oder beim Formatieren eines longs als String.
Ich denke eher, dass du die Zahlen als String (interpretiert in einer gegebenen Basis) einlesen sollst, dann normal eine arithmetische Operation ausführen sollst, und dann das Ergebnis wieder in die Zielbasis interpretiert als String ausgeben sollst.

Ist es auch nur mit einer Methode möglich? Oder brauche ich dafür mehrere?
 

httpdigest

Top Contributor
Okay, nachdem ich die Aufgabenstellung nochmal gelesen habe, sollst du anscheinend die übergebenen long-Parameter erstmal im 10-er System interpretieren und die daraus entstehenden Werte der einzelnen Zehnerstellen (also 0 bis maximal 9) wiederum in der eigentlichen Zielbasis interpretieren.
Ich würde tatsächlich die Basiskonvertierung als separate Methode machen und die Arithmetik ganz einfach mit Standard-Javaoperatoren realisieren.
 

Guest1

Aktives Mitglied
Okay, nachdem ich die Aufgabenstellung nochmal gelesen habe, sollst du anscheinend die übergebenen long-Parameter erstmal im 10-er System interpretieren und die daraus entstehenden Werte der einzelnen Zehnerstellen (also 0 bis maximal 9) wiederum in der eigentlichen Zielbasis interpretieren.
Ich würde tatsächlich die Basiskonvertierung als separate Methode machen und die Arithmetik ganz einfach mit Standard-Javaoperatoren realisieren.

Es ist wirklich eine sehr aufwendige Aufgabe:( ich werde es versuchen.
Danke dir
 

httpdigest

Top Contributor
Na, das schaffst du schon! Hab's gerade mal gemacht und (ohne die Sonderbehandlung mit dem -1, die ich erstmal weglassen würde) sind es wirklich seeeehr kleine Einzeilermethoden. Ich würde dir raten, eine Methode `to10(long value, int sourceBase)` zu machen, die einen gegebenen Wert (interpretiert in der Quellbasis `sourceBase`) ersteinmal wieder in einen vernünftigen Wert rückwandelt (also in einen long, der dieser Wert wäre, würde er nicht in der 10-er Basis als die andere Basis interpretiert geschrieben worden sein - wenn der Satz Sinn macht :) ).
Dann würde ich eine `from10(long value, int destinationBase)` Methode bauen, die genau das Gegenteil tut: Sie nimmt einen richtig ausgerechneten Wert entgegen und konvertiert ihn so, dass der Wert wiederum als 10-er Basis interpretiert ausgegeben den richtigen String generiert. Dann brauchst du nur noch eine `add` Methode, die die beiden Parameter mit `to10` erstmal "korrigiert", dann eine Standard-Java Addition durchführt, und dann das Ergebnis mit `from10` wieder rückkonvertiert, so dass die Zahl dann eben, wenn sie etwa per System.out.println() ausgegeben wird - was ja in der Basis 10 interpretiert - nur noch Ziffern der gewünschten Basis enthält.

Für einen kurzen Test, ob die Konvertierung mit to10/from10 richtig ist, hatte ich kurz das hier verwendet: https://www.tools4noobs.com/online_tools/base_convert/
 

Guest1

Aktives Mitglied
Na, das schaffst du schon! Hab's gerade mal gemacht und (ohne die Sonderbehandlung mit dem -1, die ich erstmal weglassen würde) sind es wirklich seeeehr kleine Einzeilermethoden. Ich würde dir raten, eine Methode `to10(long value, int sourceBase)` zu machen, die einen gegebenen Wert (interpretiert in der Quellbasis `sourceBase`) ersteinmal wieder in einen vernünftigen Wert rückwandelt (also in einen long, der dieser Wert wäre, würde er nicht in der 10-er Basis als die andere Basis interpretiert geschrieben worden sein - wenn der Satz Sinn macht :) ).
Dann würde ich eine `from10(long value, int destinationBase)` Methode bauen, die genau das Gegenteil tut: Sie nimmt einen richtig ausgerechneten Wert entgegen und konvertiert ihn so, dass der Wert wiederum als 10-er Basis interpretiert ausgegeben den richtigen String generiert. Dann brauchst du nur noch eine `add` Methode, die die beiden Parameter mit `to10` erstmal "korrigiert", dann eine Standard-Java Addition durchführt, und dann das Ergebnis mit `from10` wieder rückkonvertiert, so dass die Zahl dann eben, wenn sie etwa per System.out.println() ausgegeben wird - was ja in der Basis 10 interpretiert - nur noch Ziffern der gewünschten Basis enthält.

Für einen kurzen Test, ob die Konvertierung mit to10/from10 richtig ist, hatte ich kurz das hier verwendet: https://www.tools4noobs.com/online_tools/base_convert/

Hoffentlich:)
Ich kann's nicht fasseno_O du bist doch ein Genie:cool:
Versuche die Aufgabe schon seit Stunden zu lösen.
 

httpdigest

Top Contributor
Noch kleiner Hinweis zur Behandlung von in der Zielbasis nicht darstellbaren Zahlen, wie etwa 12 zur Basis 2: Das würde ich mit Exception-Handling realisieren. Also in der (Hilfs-)methode, wo du die "Basiskorrektur" der eingegebenen Zahlen vornimmst, würde ich bei jedem Rekursionsschritt (der ja eine Ziffer der Zahl behandelt) prüfen, ob diese Ziffer >= der Zielbasis ist, in die konvertiert werden soll. Falls ja, wirf einfach eine Exception, z.B. IllegalArgumentException oder so. In der eigentlichen add() Methode würde ich diese Exception dann mit einem einfachen try {...der eigentliche Code...}catch(IllegalArgumentException e) {return -1L;} behandeln. Exception-Handling bei Rekursionen ist meist einfacher als irgendwelche Sonder-Rückgabewerte zu nutzen und die in jedem Rekursionsschritt erneut zu prüfen.
 

mihe7

Top Contributor
Ich würde empfehlen, direkt im gegebenen Zielsystem zu rechnen. Dann kann man eine kurze rekursive Methode angeben, die das Problem löst.
 

Guest1

Aktives Mitglied
Java:
public static long addiere(long zahl1, long zahl2, int basis){
     
        return (basis == 10)
                ?zahl1 + zahl2
                :addiere (zahl1, zahl2, Basis, 0,1);
    }
 
    public static long addiere(long zahl1, long zahl2, int basis,
            long zahl3, long verschiebung){
     
     
     
        long letzteZahl1= zahl1 % 10;
        long letzteZahl2= zahl2 % 10;
     
        //Berechne Ergebnis der letzten beiden Ziffern Dezimal
        long dezimalsumme= (letzteZahl1 + letzteZahl2);
     
        //Umwandlung des Dezimalergebnisses in das Ergebnis zur Basis
     
        long teilRes=((dezimalsumme >= basis)
                          ?10
                           :0)                                         //Übertrag
            +dezimalsumme >= basis                      //+Rest 
                ?dezimalsumme - basis 
                :dezimalsumme;
     
        //Addiere das Ergebnis (zur Basis)zur vorherigen Dezimals
     
        dezimalsumme= (zahl3 + teilRes * verschiebung);
     
        //Erweitere die Basis zum abschneiden des Übertrags der Dezimalsumme
     
        long basisCut= basis * verschiebung * ((teilRes >= 10) ? 10 :1);
     
        //umwandlung
     
        long res = (verschiebung == 1)
                    ?teilRes
                    : ((dezimalsumme >= basisCut)  //Übertrag
                        ?verschiebung * 10
                        :0)
                    + ((dezimalsumme >= basisCut)  //Rest
                        ?dezimalsumme - basisCut
                        :dezimalsumme);
                 
     
        return (letzteZahl1 >= basis || letzteZahl2 >= basis) ? -1
                : (( zahl1 != 0  || zahl2 != 0)
                ?addiere(zahl1 / 10, zahl2 / 10, basis, res, verschiebung * 10)
                :res);
     
    }
Ist das so in Ordnung oder geht das ganze auch noch kürzer? :)
 
Zuletzt bearbeitet von einem Moderator:

mihe7

Top Contributor
Der Ansatz deckt sich mit dem, was ich gemacht hätte. Weiß allerdings nicht, ob der Code in Ordnung ist; der ist mir zu kompliziert :p

Einfacher wird es, wenn Du die rekursive Funktion nicht als Addition von zwei sondern von drei Summanden auffasst.

Für die Ziffer/Übertrag im Zielsystem rechne einfach % basis bzw. / basis.
 
X

Xyz1

Gast
Hi, kannst Du es nicht in [noparse]
Java:
...
[/noparse]-Tags tun?;)
 

Guest1

Aktives Mitglied
Der Ansatz deckt sich mit dem, was ich gemacht hätte. Weiß allerdings nicht, ob der Code in Ordnung ist; der ist mir zu kompliziert :p

Einfacher wird es, wenn Du die rekursive Funktion nicht als Addition von zwei sondern von drei Summanden auffasst.

Für die Ziffer/Übertrag im Zielsystem rechne einfach % basis bzw. / basis.

Okay:D
 

httpdigest

Top Contributor
Da du ja schon eine Lösung genannt hast, hier noch meine (mit einer Basistransformation und Addition per Standard-Java-Operator) mit samt Check auf in der Zielbasis nicht repräsentierbare Ziffern:
Java:
private static long cvt(long v, int sb, int db) {
  long t = v % sb;
  if (t >= db)
    throw new IllegalArgumentException();
  return v > 0 ? db * cvt(v / sb, sb, db) + t : 0;
}
public static long add(long a, long b, int base) {
  try {
    return cvt(cvt(a, 10, base) + cvt(b, 10, base), base, 10);
  } catch (IllegalArgumentException e) {
    return -1L;
  }
}
 

mihe7

Top Contributor
Da ist meine ja lang dagegen:
Java:
    private static long add(long z1, long z2, int base,
                                int carry, long weight) {
        if (z1 == 0 && z2 == 0 && carry == 0) {
            return 0;
        }

        int digit1 = (int)(z1 % 10);
        int digit2 = (int)(z2 % 10);
        if (digit1 >= base || digit2 >= base) {
            return -1L;
        }

        int sum = carry + digit1 + digit2;
        int digit = sum % base;
        long rest = add(z1/10, z2/10, base, sum/base, weight*10);
        return rest >= 0 ? digit*weight + rest : -1L;
    }
 

JerryB.

Neues Mitglied
Habt ihr eigentlich auch Buch Empfehlungen zum Einstieg in Java?
Hallo Guest1,
Also ich wurde dir dieses Buch empfehlen: http://openbook.rheinwerk-verlag.de/javainsel/
Ich bin momentan auch ein Anfänger, aber seitdem ich das Buch benutzte, verstehe ich die Sachen ein wenig besser.
Ist nicht unbedingt das beste Buch, aber für den Einstieg - meiner Meinung nach- optimal.:)
Aber wie gesagt , es gibt auch andere gute Bücher.
 

Neue Themen


Oben