# Zahldarstellung zur Basis 2,4,8 und 10



## Guest1 (4. Dez 2018)

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


----------



## httpdigest (4. Dez 2018)

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 (4. Dez 2018)

httpdigest hat gesagt.:


> 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 (4. Dez 2018)

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 (4. Dez 2018)

httpdigest hat gesagt.:


> 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 (4. Dez 2018)

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 (4. Dez 2018)

httpdigest hat gesagt.:


> 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 fassen du bist doch ein Genie
Versuche die Aufgabe schon seit Stunden zu lösen.


----------



## httpdigest (4. Dez 2018)

Nee, viiiele viiiele Jahre Übung macht den Meister.


----------



## httpdigest (4. Dez 2018)

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 (5. Dez 2018)

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


----------



## Guest1 (5. Dez 2018)

```
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?


----------



## mihe7 (5. Dez 2018)

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  

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.


----------



## Xyz1 (5. Dez 2018)

Hi, kannst Du es nicht in [noparse]
	
	
	
	





```
...
```
[/noparse]-`Tags` tun?


----------



## Guest1 (5. Dez 2018)

mihe7 hat gesagt.:


> 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
> 
> 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


----------



## Guest1 (5. Dez 2018)

DerWissende hat gesagt.:


> Hi, kannst Du es nicht in [noparse]
> 
> 
> 
> ...



Bisher wurde uns nur rekursion(ohne schleifen und ohne string operationen) beigebracht 
Trotzdem danke


----------



## Robat (5. Dez 2018)

Guest1 hat gesagt.:


> Bisher wurde uns nur rekursion(ohne schleifen und ohne string operationen) beigebracht
> Trotzdem danke


Was @DerWissende dir eigentlich sagen wollte: Pack deinen Code bitte in Code-Tags [code=Java] ... Dein Code .. [/code] .. dann wird der Code auch besser dargestellt.


----------



## Guest1 (5. Dez 2018)

Robat hat gesagt.:


> Was @DerWissende dir eigentlich sagen wollte: Pack deinen Code bitte in Code-Tags [code=Java] ... Dein Code .. [/code] .. dann wird der Code auch besser dargestellt.



Achso okay


----------



## Guest1 (5. Dez 2018)

Habt ihr eigentlich auch Buch Empfehlungen zum Einstieg in Java?


----------



## mihe7 (5. Dez 2018)

@Guest1 das ist eine Frage für @Javinner


----------



## httpdigest (5. Dez 2018)

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:

```
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 (5. Dez 2018)

@httpdigest der Rekursionsguru


----------



## mihe7 (5. Dez 2018)

Da ist meine ja lang dagegen:

```
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. (7. Dez 2018)

Guest1 hat gesagt.:


> 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.


----------

