# Java Horner Schema



## alexschmid97 (21. Nov 2015)

Hallo,

ich muss eine Aufgabe lösen in der ich ein übergebenes binär Array mit Hilfe des Hornerschemas in eine int Zahl umwandele.

ich hab mir das Hörnerschema schon gefühlt 100 mal auf Papier aufgezeichnet, komme aber irgendwie nicht dahinter wie ich die einträge in meinem Array miteinander addieren bzw multiplizieren muss. 

hier ist mal mein Code :


```
int[] f = { 0, 0, 1, 0, 0, 0, 0, 0 };

        int h_schema = binaryToInteger(f);

        System.out.println("Das Hornerschema ergibt: " + h_schema);


public static int binaryToInteger(int []number) {
       
        int horner=0;
        for (int i=0 ; i<number.length ; i++) {
           
             horner+=number[i]*2;
            }
       
        horner*=horner;
        return horner;
```


----------



## Khal Drogo (21. Nov 2015)

Stehen die Most Significant Bits am Anfang oder am Ende deines Arrays? (Ich gehe mal davon aus, dass das MSB in _number[0]_ steht, sodass f der Dezimalzahl 32 entspricht(?)).
Musst du in der Zeile _horner += number * 2;_ die Nummer mit einer entsprechenden Zweierpotenz und nicht mit 2 multiplizieren.
Was erwartest du dir von der Zeile _horner *= horner;_?
_

Mit freundlichen Grüßen
Xelsarion_


----------



## Tarrew (21. Nov 2015)

Die Berechnung innerhalb der for-Schleife beruht wohl darauf:
Die Zahl 1001 würde sich so in eine dezimale Zahl umformen lassen:

1*2^3 + 0*2^2 + 0*2^1 + 1*2^0,
das ist aber genau das gleiche wie:

(((((1*2)+0)*2)+0)*2)+1. Und auf dieser Tatsache beruht wohl die ganze Methode.
Allerdings ist die richtige Klammersetzung im Quellcode nicht umgesetzt worden.

Was du jetzt machst ist:

```
horner=horner+(number[i]*2);
```
was du aber machen willst ist:

```
horner=(horner+number[i])*2;
```

Wie du mit dem niederwertigsten Bit umgehst solltest du dir dann auch nochmal angucken.


----------



## Khal Drogo (21. Nov 2015)

Für mich sieht es mit seiner for-Schleife eher so aus, als wöllte er es nicht so klammern, wie du es ausgeführt hast. Falls das aber der Fall ist, sollte er mit deinen Tipps jetzt was anfangen können 

Mit freundlichen Grüßen
Xelsarion


----------



## alexschmid97 (21. Nov 2015)

ahh natürlich jetzt wird mir einiges klar  das mit den Klammern hab ich genau so machen wollen
ok also ich habe jetzt den Code geändert. Jetzt kommt als Lösung 64 heraus, was 1 schleifendurchlauf zu viel ist. müsste an meinem startwert liegen oder ?
mein MSB ist das erste bit, wenn es 1 wäre hab ich schon die passende Methode bereit um es zu konvertieren


----------



## alexschmid97 (21. Nov 2015)

das array beginnt ja einen Eintrag vorher schon zu zählen an


----------



## Tarrew (21. Nov 2015)

Der Startwert ist okay. Nur der Endwert passt nicht. Du läufst einen zu weit. Das letzte Bit musst du nur noch addieren wie in der Beispielrechnung.


alexschmid97 hat gesagt.:


> das array beginnt ja einen Eintrag vorher schon zu zählen an


Was meinst du damit? Du fängst bei number[0] an, das passt alles.


----------



## alexschmid97 (21. Nov 2015)

alles klar habe kapiert, kommen auch richtige Ergebnisse raus, danke man


----------



## alexschmid97 (21. Nov 2015)

```
public static int binaryToInteger(int[] number) {

        int horner = 0;
        boolean a = (number[0] == 1);
        for (int i = 0; i < number.length-1; i++) {

            horner = (horner + number[i]) * 2;

            }
            if (a) {
            number = convertToTwosComplement(number);
        }

        horner=horner+number[7];
        return horner;
```


----------



## Khal Drogo (21. Nov 2015)

Bekommt ihr nur Arrays der Länge 8? Ansonsten solltest du die entsprechende Zeile möglicherweise durch 
	
	
	
	





```
horner = horner + number[number.length - 1];
```
 ersetzen. Dann hast du das ganze allgemein gelöst, was ja vielleicht ganz wünschenswert wäre.

Mit freundlichen Grüßen
Xelsarion


----------



## alexschmid97 (21. Nov 2015)

ne, also bei mir funktioniert es perfekt,  dafür habe ich jetzt ein ganz anderes Problem, 

in der nächsten Nummer habe ich ein binäres Array. dieses soll ich jetzt um ein anderes binäres array der selben Länge nach Rechts stiften. Problem an der Sache ist, dass ich die beiden array nicht in dezimal Schreibweise umformen darf. Push also da hab ich jetzt keine Ahnung wie ich ansetzten soll.
ich hoffe ihr könnt mir helfen. 
eventuell muss man den Betreff des Themas ändern, bin nur noch ziemlich neu , deshalb weiß ich nicht wie das geht 

lg Alex


----------



## Khal Drogo (21. Nov 2015)

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

Mit freundlichen Grüßen
Xelsarion


----------



## JStein52 (22. Nov 2015)

Also du hast:


```
int [] array1;
int [] array2;
```

Diese arrays enthalten 0en oder 1en und du darfst aber deine eigene binaryToInteger nicht verwenden um z.B. die die Anzahl der shifts die in array2 stehen zu ermitteln ??

@Xelsarion  da hilft ihm dein Link glaube ich nicht weiter ?!


----------



## alexschmid97 (22. Nov 2015)

ich darf weder die Binärzahlen umwandeln noch irgendwelche anderen Methoden verwenden die ich nicht selber geschrieben habe


----------



## JStein52 (22. Nov 2015)

Hmm, binaryToInteger hättest du ja selbst geschrieben aber das gilt hier wohl nicht 
Aber ich glaube letzten Endes wirst du das zweite Array in eine Dezimalzahl umwandeln müssen, auch wenn es vielleicht eher implizit geschieht. Du könntest z.B. im zweiten Array nachsehen ob das n.te Bit gesetzt ist und dann shiftest du um 2^n nach rechts. Und das ganze machst du in einer Schleife über alle elemente des Arrays.
Damit hast du das zweite array nicht explizit in eine Integerzahl umgewandelt.


----------



## Khal Drogo (22. Nov 2015)

@JStein52: Ja, dachte eher, es hängt am Shift.

Mit freundlichen Grüßen
Xelsarion


----------



## alexschmid97 (22. Nov 2015)

ja da hast du recht, anders würde es glaube ich nicht gehen, wenn ich jetzt mal einfach mein array umwandele  dann müsste es doch eigentlich so gehen oder?

kriege als Lösung immer 00000000 heraus, egal wie ich stifte


----------



## alexschmid97 (22. Nov 2015)

```
public static int[] shiftRight (int[] input, int[]numberOfentries) {
       
        int [] arrayshifted= new int [numberOfbits];
        int shiftnumber= binaryToInteger(numberOfentries);
       
        for (int i=0 ; i<arrayshifted.length ; i++) {
            arrayshifted[i+shiftnumber]=input[i];
           
        }
        return arrayshifted;
   
    }
```


----------



## JStein52 (22. Nov 2015)

sieht eigentlich richtig aus.  Hast du dir mal mit dem Debugger oder per println die relevanten Daten
in dieser Methode angeschaut ? shiftnumber, und den Inhalt von input ? numberOfbits ist eine Konstante die sinnvoll belegt ist ?

Edit: ich sehe gerade, ist die Schleifenbedingung denn richtig ? Du darfst ja nicht das ganze array durchlaufen sonst kriegst du irgendwann  eine IndexOutOfBoundsException an dieser Stelle:  arrayshifted[i+shiftnumber]


----------



## alexschmid97 (22. Nov 2015)

hmm also die eingegebenen Daten müssten stimmen. numberOfbits ist immer 8 und die shiftnumber stimmt auch. Das mit der Schleife kann sein, aber er gibt ja auch keine Fehlermeldung aus, nur die Lösung 00000000, 
der Fehler liegt aber bestimmt an der Schleife


----------



## JStein52 (22. Nov 2015)

Das kann eigentlich nicht sein, sobald shiftnumber  grösser 0 ist muss es doch knallen. Die Schleife darf nur so weit laufen:


```
public static int[] shiftRight (int[] input, int[]numberOfentries) {
     
        int [] arrayshifted= new int [numberOfbits];
        int shiftnumber= binaryToInteger(numberOfentries);
     
        for (int i=0 ; i<(arrayshifted.length-shiftnumber) ; i++) {
            arrayshifted[i+shiftnumber]=input[i];
         
        }
        return arrayshifted;
 
    }
```

woher weisst du dass deine Daten stimmen ? hast du sie dir ausgegeben oder im Debugger angeschaut ??

Poste mal den relevante Code der diese Methode aufruft


----------



## JStein52 (22. Nov 2015)

Ich habe es gerade bei mir ausprobiert. Diese Methode funktioniert wenn du das mit der Schleife korrigierst und wenn du sie mit vernünftigen Daten aufrufst !!


----------



## alexschmid97 (22. Nov 2015)

Ok, ich teste es mal schreib dann ob es funktioniert hat. Das mit der Schleife müsste dann ja jetzt so klappen, könne ja keine nicht definierten Werte rauskommen.


----------



## alexschmid97 (22. Nov 2015)

ja genial, jetzt klappt alles, es werden richtige Ergebnisse ausgegeben, lag dann nur an dem Schleifendurchlauf . Danke für die ausführliche Antworten.


----------



## alexschmid97 (22. Nov 2015)

es muss ich nur noch meinen Tutor fragen, ob ich das Array überhaupt umformen darf


----------



## JStein52 (22. Nov 2015)

Ok, schön. Und falls nicht ist es weiter kein Beinbruch. Dann brauchst du nur eine weitere Schleife in der du nachschaust ob in numberOfEntries das n.te Bit gesetzt ist und dann shiftest du um 2^n nach rechts. Den Teil hast du ja schon.


----------

