# Hexadezimal in Dezimal



## eclipseworker (15. Nov 2011)

Zu erst ich weiß, dass das niemand so porgrammieren würde. Es geht mir mehr um die Funktionen als um das Programmierziel. Also bitte mit Bezug auf den Code antworten. Ich will einen String eingeben, der soll als Hexadezimalzahl begriffen werden und dann als Dezimalzahl retour gegeben, also zum Beispiel "FF" und dann 255 zurück bekommen. Dazu verwende ich diesen Code:

```
public class HexadezimalToDezimal
{
    // Instanzvariablen - ersetzen Sie das folgende Beispiel mit Ihren Variablen
    private String myString;
    private char[] myCharArray;
    private int[] myZahlDezimal;
    private int kontroll;
    private int summe;
    private boolean pruefsumme;
    /**
     * Konstruktor für Objekte der Klasse stringtochar
     */
    public HexadezimalToDezimal(String hexaZahl)
    {
        myString=hexaZahl;
        myCharArray=myString.toCharArray();
        kontroll=0;
        if(gueltigerString(myCharArray)==true){
            summeBrechnen();
            System.out.println("Die Hexadezimalzahl "+hexaZahl+" hat den dezimalen Wert von "+summe+".");
        } else {
            System.out.println("Ungueltige Eingabe!");
        }
   }
        public boolean gueltigerString(char [] myCharArray2){
        for (int i=0;i<myCharArray2.length; i++){
           switch (myCharArray2[i]){
               case '0': myZahlDezimal[i]=0;  break;
               case '1': myZahlDezimal[i]=1;  break;
               case '2': myZahlDezimal[i]=2;  break;
               case '3': myZahlDezimal[i]=3;  break;
               case '4': myZahlDezimal[i]=4;  break;
               case '5': myZahlDezimal[i]=5;  break;
               case '6': myZahlDezimal[i]=6;  break;
               case '7': myZahlDezimal[i]=7;  break;
               case '8': myZahlDezimal[i]=8;  break;
               case '9': myZahlDezimal[i]=9;  break;
               case 'A': myZahlDezimal[i]=10; break;
               case 'a': myZahlDezimal[i]=10; break; 
               case 'B': myZahlDezimal[i]=11; break;
               case 'b': myZahlDezimal[i]=11; break;
               case 'C': myZahlDezimal[i]=12; break;
               case 'c': myZahlDezimal[i]=12; break;
               case 'D': myZahlDezimal[i]=13; break;
               case 'd': myZahlDezimal[i]=13; break;
               case 'E': myZahlDezimal[i]=14; break;
               case 'e': myZahlDezimal[i]=14; break;
               case 'F': myZahlDezimal[i]=15; break;
               case 'f': myZahlDezimal[i]=15; break;
               default:  kontroll=-1; break;
           }
        }
        if (kontroll==-1){
            return false;
        } else {
            return true;
        }
   }
   
   public void summeBrechnen(){
        for (int i=0;i<myZahlDezimal.length; i++){  
            summe=summe+Math.pow(myZahlDezimal[i],i);
        }
   }

    
}
```
Mein erstes Problem ist das mir der Compiler bei 
	
	
	
	





```
... Math.pow(myZahlDezimal[i],i);
```
 sagt "possible lost of expression, found double, expected int" Wie ist das möglich (den myZahlDezimal[] ist ein int-Arry)? Wenn ich das mit 
	
	
	
	





```
... (myZahlDezimal[i]^i);
```
 umgehe (wo ich nicht weiß ob das so passt) kompliert er es mir zwar gibt aber bei Aufruf diese Fehlermeldung aus:
java.lang.NullPointerException
	at HexadezimalToDezimal.gueltigerString(HexadezimalToDezimal.java:50)
	at HexadezimalToDezimal.<init>(HexadezimalToDezimal.java:25)
Also was mache ich hier falsch? :rtfm:


----------



## nrg (15. Nov 2011)

Math.pow liefert einen double. Du addierst diesen double mit einem int was wiederrum ein double ergibt und willst diesen double in einen int schreiben. Das geht so nicht, weil double genauer als int ist und deshalb benötigst du hier einen expliziten cast:


```
summe=summe+(int)Math.pow(myZahlDezimal[i],i);
```


----------



## SlaterB (15. Nov 2011)

die NullPointerException kommt in jedem Fall, ist eigentlich extrem leicht selber herauszufinden,
welche Zeile ist betroffen, auf welches Objekt wird dort zugriffen? -> myZahlDezimal ist null, ganz ganz einfach


----------



## Michael... (15. Nov 2011)

eclipseworker hat gesagt.:


> Mein erstes Problem ist das mir der Compiler bei
> 
> 
> 
> ...


Math.pow liefert nun mal ein double als Ergebnis, da Du aber einen int potenzierst kannst Du ja einfach nach int casten.


eclipseworker hat gesagt.:


> Wenn ich das mit
> 
> 
> 
> ...


Du hast vergessen das int-Array zu initialisieren.

Abgesehen davon ist die Formel zu Berechnung der Dezimalzahl falsch.


----------



## eclipseworker (15. Nov 2011)

SlaterB hat gesagt.:


> die NullPointerException kommt in jedem Fall, ist eigentlich extrem leicht selber herauszufinden,
> welche Zeile ist betroffen, auf welches Objekt wird dort zugriffen? -> myZahlDezimal ist null, ganz ganz einfach



Es ist die Betroffene Zeile im switch betroffen von case '0' bis default und genau deshalb habe ich diese Schleife um myZahlDezimal[] zu inzializieren.


----------



## SlaterB (15. Nov 2011)

noch eine Frage offen?


----------



## eclipseworker (15. Nov 2011)

Ja. Warum haut er mir den Nullpointerexpection genau dort rein wo ich myDezimalzahl[] inzialisieren/verändern möchte?


----------



## nrg (15. Nov 2011)

es fehlt halt einfach die Instanziierung des Arrays:


```
myZahlDezimal = new int[...]
```


----------



## eclipseworker (15. Nov 2011)

nrg hat gesagt.:


> es fehlt halt einfach die Instanziierung des Arrays:
> 
> 
> ```
> ...



Ok das habe ich jetzt verstanden und mit 
	
	
	
	





```
myZahlDezimal = new int[myCharArray.length]
```
 im Konstruktor inzialisert. Also laufen tut es jetzt das Ergebniss ist zwar falsch aber immer hin laufen tut es.


----------



## Landei (15. Nov 2011)

Gratis-Tipp: Statt 


```
switch (myCharArray2[i]){
    ...             
    case 'A': myZahlDezimal[i]=10; break;
    case 'a': myZahlDezimal[i]=10; break; 
    ...
}
```

kannst du 


```
switch (myCharArray2[i]){
    ...             
    case 'A': case 'a' : myZahlDezimal[i]=10; break;
    ...
}
```

schreiben, oder dir mit [c]Character.toLowerCase(myCharArray2_)[/c] die Groß/Kleinschreibungsunterscheidung sparen. Natürlich wäre 



		Java:In die Zwischenablage kopieren


myZahlDezimal[i] = "0123456789abcdef".indexOf(Character.toLowerCase(myCharArray2[i]));


statt [c]switch[/c] wesentlich kürzer._


----------



## irgendjemand (15. Nov 2011)

mal davon abgesehen das das hier

```
byte^byte
```
keine potenz sondern ein BITWISE XOR ist geht das ganze auch deutlicher einfacher wenn man sich nur mal die API-Doc durchlesen würde

static int Integer.parseInt(String, int)

mit dieser methode kannst du einen string mit einem bestimmten radix parsen ...

radix hat dabei einen wertebereich von 2 - 36 *oder sowas ähnliches* und meint damit den zeichenumfang ...

BIN : 2
OCT : 8
DEC : 10
HEX : 16

willst du also einen HEX-String in einen INT parsen machst du das einfach so


```
int dec=Integer.parseInt("aabbccdd", 16);
```

zu beachten : INT hat einen maximalen wertebereich von -2^31 - +2^31-1 ... also rund von -2milliarden bis +2milliarden ... heißt also wenn du einen HEX parsen willst der diese rund +2milliarden überschreitet hast du einen type-overflow und bekommst einen falschen wert ...


----------



## eclipseworker (15. Nov 2011)

Danke die Ursprungsfragen wurden beantwortet. 
Jetzt ist meine Frage wo es bei der Berechnung hackt denn wenn ich das zu Fuß rechne gehe ich doch genauso vor wie dieser Lograithmus: 

```
public void summeBrechnen(){
        for (int i=0;i<myZahlDezimal.length; i++){  
            summe=summe+(int)Math.pow(myZahlDezimal[i],i);
        }
   }
```
Sprich ich habe mir in der Funktion 
	
	
	
	





```
gueltigerString(myCharArray)
```
 die Zehneräquivalenzen zu jedem Zeichen überlegt und sage die Wertigkeit an der Stelle i ist myZahlDezimal_^i und die muss ich zur ersten Summe dazu zählen bis ich myZahlDezimal.length erreicht habe._


----------



## SlaterB (15. Nov 2011)

rechne dochmal ein Beispiel, nehmen wir AA, ganz konkret auf Papier aus, schreibe hier die Zwischenwerte usw. auf,
vergleiche Schritt für Schritt was bei myZahlDezimal_^i rauskommt usw.!
sind ja praktisch nur 2-3 Zahlen.._


----------



## eclipseworker (15. Nov 2011)

SlaterB hat gesagt.:


> rechne dochmal ein Beispiel, nehmen wir AA, ganz konkret auf Papier aus, schreibe hier die Zwischenwerte usw. auf,
> vergleiche Schritt für Schritt was bei myZahlDezimal_^i rauskommt usw.!
> sind ja praktisch nur 2-3 Zahlen.._


_
OK: 
summe=0;
summe=summe+10^16
Aha Fehler erkannt es gehört:
myZahlDezimal*(16^i). Habe meinen Code entsprechend modifiziert.
dann:
Erster Schritt:
summe=0;
summe=summe+10*(16^0) also summe=0+10*(16^0)=10
Zweiter Schritt:
summe=summe+10*(16^1) also summe=16+10*(16^1)=170
Das stimmt und das gibt mein Programm auch aus.
Danke. Problem gelöst! :toll:_


----------



## eclipseworker (15. Nov 2011)

Ok das Problem ist noch nicht ganz gelöst mit 

```
public void summeBrechnen(){
        for (int i=myZahlDezimal.length-1;i>=0; i--){  
            summe=summe+myZahlDezimal[i]*(int)Math.pow(16,i);
        }
   }
```
rechnet er seitenverkehrt, also ich bekomme bei A0 10 und bei 0A 160 heraus. Der Grund warum es mit AA ging war die Seitengleichheit. Was kann man hier tun?


----------



## SlaterB (15. Nov 2011)

da habe ich in der Tat ein schlechtes Beispiel gegriffen, anderseits ganz gut die Fehler nacheinander anzugehen
und erfreulich dass du selber schon einiges weiteres herausgefunden hast,

Lösungsmöglichkeiten wären eigentlich nicht so schwer,
das Array andersrum befüllen ist vielleicht zu verwirrend, aber statt Math.pow(16,i) könnte mit einem anderen Exponent gerechnet werden,
mit [c]int i=myZahlDezimal.length-1[/c] hast du doch schon eine vergleichbar komplizierte Rechnung, so ähnlich kannst du an den richtigen Exponenten kommen,
die Durchlaufrichtung des Arrays ist bei einfacher Summe in der Tat egal, kannst du wieder auf normal zurückstellen, das ist weniger Code


----------



## eclipseworker (15. Nov 2011)

SlaterB hat gesagt.:


> da habe ich in der Tat ein schlechtes Beispiel gegriffen, anderseits ganz gut die Fehler nacheinander anzugehen
> und erfreulich dass du selber schon einiges weiteres herausgefunden hast,
> 
> Lösungsmöglichkeiten wären eigentlich nicht so schwer,
> ...



Wie meinst du das mit anders herum befüllen? Wie soll das gehen? Denn 
	
	
	
	





```
for(int i=myZahlDezimal.length-1; i>=0;i--)
```
 und 
	
	
	
	





```
for(int i=0; i<myZahlDezimal.length;i++)
```
 tun genau dasselbe.


----------



## SlaterB (15. Nov 2011)

der Durchlauf der Arrays ist egal, ja, schrieb ich in der letzten Zeile auch

andersrum befüllen wäre ein Arrayinhalt 10, 0 statt 0, 10, das wäre dann wirklich ein Unterschied,
aber wie gesagt nicht unbedingt nötig, du kannst auch durch Mathematik dafür sorgen dass bei 
Math.pow(16,i) statt des falschen i etwas besseres steht


----------



## Michael... (15. Nov 2011)

genau, deshalb muss Du die Laufvariable "invertieren" wenn i==0 ist greifst Du ja auf die höchstwertige Stelle des Arrays zu und der Exponent der Funktion müsste eigentlich Länge-1 sein, bei i==1 muss er Länge-2 sein, usw. das meinte Slater mit "vergleichbar komplizierte Rechnung"


----------



## eclipseworker (15. Nov 2011)

Michael... hat gesagt.:


> genau, deshalb muss Du die Laufvariable "invertieren" wenn i==0 ist greifst Du ja auf die höchstwertige Stelle des Arrays zu und der Exponent der Funktion müsste eigentlich Länge-1 sein, bei i==1 muss er Länge-2 sein, usw. das meinte Slater mit "vergleichbar komplizierte Rechnung"


Ich habe es so versucht 
	
	
	
	





```
case '0': myZahlDezimal[myCharArray2.length-i]=0;  break;
```
 aber das gibt die Fehlermeldung:
java.lang.ArrayIndexOutOfBoundsException: 2
	at HexadezimalToDezimal.gueltigerString(HexadezimalToDezimal.java:36)
	at HexadezimalToDezimal.<init>(HexadezimalToDezimal.java:26)


----------



## SlaterB (15. Nov 2011)

Länge-1, du hast Länge drin, -1 nicht, 
so einfache Indexe sollten doch eigentlich zu überblicken sein

wie gesagt: entweder im Array die Position tauschen, das machst du gerade, oder alternativ später bei Math.pow() den Index drehen,
das ist ziemlich äquivalent, falls sonst egal ist wierum das Array aufgebaut ist


----------



## eclipseworker (15. Nov 2011)

SlaterB hat gesagt.:


> Länge-1, du hast Länge drin, -1 nicht,
> so einfache Indexe sollten doch eigentlich zu überblicken sein
> 
> wie gesagt: entweder im Array die Position tauschen, das machst du gerade, oder alternativ später bei Math.pow() den Index drehen,
> das ist ziemlich äquivalent, falls sonst egal ist wierum das Array aufgebaut ist



Ich weiß zwar immer noch nicht wie ich den array verdrehe, aber 
	
	
	
	





```
Math.pow(i,16)
```
 statt 
	
	
	
	





```
Math.pow(16,i)
```
 hat gewirkt. Bei "0a" bei "AA" ist es jetzt plötzlich falsch.


----------



## Michael... (15. Nov 2011)

eclipseworker hat gesagt.:


> Ich weiß zwar immer noch nicht wie ich den array verdrehe, aber
> 
> 
> 
> ...


Math.pow(i, 16) war schon immer falsch und wurde bisher doch nirgendwo verwendet?
Für Hex System war schon immer die 16 die Basis ;-)
Entscheidend für die Potenzierung ist das i zur Wertigkeit der Stelle passt.

Beispiel:

```
0x7A4 = 7 * 16^2 + 10 * 16^1 + 4 * 16^0
```

Du kannst ja das char-Array wie bisher in ein int-Array umwandeln, bei der Potenzierung musst Du nur beachten, dass der Schleifen-Zähler bzw. die Indizes entgegengesetzt zu der Wertigkeit und somit dem notwendigen Exponenten läuft.

Auf das Bespiel oben bezogen bedeutet es, dass der Schleifenzähler i von 0 bis 2 läuft während der Exponent von 2 bis 0 laufen muss.


----------



## eclipseworker (15. Nov 2011)

Michael... hat gesagt.:


> Math.pow(i, 16) war schon immer falsch und wurde bisher doch nirgendwo verwendet?
> Für Hex System war schon immer die 16 die Basis ;-)
> Entscheidend für die Potenzierung ist das i zur Wertigkeit der Stelle passt.
> 
> ...



Das habe ich mit einer zweiten Schleife versucht:

```
public void summeBrechnen(){
    for (int i=0; i<myZahlDezimal.length;i++){  
        for(int j=myZahlDezimal.length-1; i>=0;j--){
            System.out.println("Element: "+i);
            System.out.println("Zahl: "+myZahlDezimal[i]);
            System.out.println("Exponent: "+j);
            //summe=summe+myZahlDezimal[i]*(int)Math.pow(j,16);
        }
    }
  }
```
Die Ausgabe habe ich geschrieben da diese Methode schief geht: Nun i bleibt immer 0, und j düst gegen -unendlich.


----------



## SlaterB (15. Nov 2011)

wer schreibt denn von zweiter Schleife? das ist doch abenteuerlich,
nein, die Summe war doch schon ziemlich gut, nur mit falschen Exponent


```
for (int i=0;i<myZahlDezimal.length; i++){  
            summe += myZahlDezimal[i] * Math.pow(16, myZahlDezimal.length-1-i);
        }
```
ist es


----------



## eclipseworker (15. Nov 2011)

SlaterB hat gesagt.:


> wer schreibt denn von zweiter Schleife? das ist doch abenteuerlich,
> nein, die Summe war doch schon ziemlich gut, nur mit falschen Exponent
> 
> 
> ...



Damit funktioniert es!!!!  :applaus:


----------

