# Horner-Schema



## Gast (29. Jan 2007)

Kann mir einer helfen?

Aufgabenstellung ist wie folgt:

Schreiben Sie eine Klasse Horner, die das Horner-Schema zur
Umwandlung aus dem Dezimalsystem in das Dual-, Octal- und
Hexadezimalsystem in folgender Weise implementiert:

• Die Methode public String horner (int number, int base) führt das
Horner-Schema aus; der Parameter number bezeichnet die umzurechnende
Zahl im Dezimalsystem, der Parameter base die Basis des Zielsystems
(wiederum gegeben im Dezimalsystem)

• Zulässige Angaben für number sind alle natürlichen Zahlen >= 0; für base
sind dies die Werte 2, 8 und 16. Wird für base ein anderer Wert als einer
dieser drei angegeben, soll die Methode eine Ausnahme auslösen:
  throw new Exception("<Text>");

• Schreiben Sie eine Main-Methode. In dieser soll es ermöglicht werden eine
Zahl von der Tastatur einzulesen. Diese soll mit Hilfe der Methode horner in
das Dual-, Octal- und Hexadezimalsystem umgewandelt und ausgegeben
werden.


----------



## The_S (29. Jan 2007)

Wir machen keine Hausaufgaben. Bei konkreten Problemen kannst du dich jedoch gerne an uns wenden  .


----------



## masta // thomas (29. Jan 2007)

Deine Hausaufgaben solltest du schon alleine machen. Fragen kannst du, wenn du an irgendeiner Stelle nicht weiterkommst.


----------



## Azrahel (29. Jan 2007)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> Wir machen keine Hausaufgaben. Bei konkreten Problemen kannst du dich jedoch gerne an uns wenden  .



Sag mal der Satz müsste doch eigentlich schon irgendwo als Tempate rumliegen oder?


----------



## The_S (29. Jan 2007)

Hm, könnten ja nen Tag einbauen, z. B. :nohomework: , der dann automatisch durch diesen Satz ersetzt wird *g*


----------



## KSG9|sebastian (29. Jan 2007)

Azrahel hat gesagt.:
			
		

> Sag mal der Satz müsste doch eigentlich schon irgendwo als Tempate rumliegen oder?


Das wäre mal was. Ein neuer Button "Wir machen keine Hausaufgaben" 

Wo kommste da denn nicht weiter?


----------



## DocRandom (29. Jan 2007)

Hallo Gast!

Ich mache sicherlich auch Deine HA nicht, aber möchte Dir zumindest einen Lösungsansatz bieten.
Hier die Code-Schnipsel:
z.B.: die Ausnahme für die falsche Basenangabe

```
package gast;

public class IllegalNumberSystemException extends Exception{

	/**
	 * Constructs a new IllegalNumberSystemException
	 * 
	 * @param e The The error message to report.
	 */
	public IllegalNumberSystemException(String e) {
		super(e);
	}
}
```
Hier das Grundgerüst für Deine Horner-Klasse

```
package gast;

public class Horner {

	private String ausgabe;
	
	public Horner() {
		ausgabe = new String("keine oder ungültige Zahl angegeben!");
	};
	
	public String horner( int number, int base)throws IllegalNumberSystemException {
		
		switch (base) {
			case 2:
				ausgabe = new String(dual(number));
				break;
			case 8:
				ausgabe = new String(octal(number));
				break;
			case 16:
				ausgabe = new String(hexa(number));
				break;
			default:
				throw new IllegalNumberSystemException("Ungültiges Zahlensystem "+number);
		}
		return ausgabe;
	}
	private String dual(int nummer) {
		
	}
	private String octal(int nummer) {
		
	}
	private String hexa (int nummer) {
		
	}
}
```
..den Rest mußt Du Dir schon selber schreiben.

mfg
DocRandom


----------



## Gast (30. Jan 2007)

Danke DocRandom.
Sorry Jungs, sollte natürlich nicht so rüber kommen dass ihr meine Hausaufgaben macht, aber ich saß doch schon ne weile an der Aufgabe und kam einfach nicht vorwärts!
Danek trotzdem nochmal!


----------



## markus_cheers (24. Aug 2008)

Ich hab ein ähnliches Problem...

Ich will ein java Programm schreiben das ein Zahl von dezimal in dual umrechnet...

Jetzt müsst ich nur noch das Ergebnis irgendwie umdrehen, oder?

Das dürfte doch nicht so schwer sein...

Danke schon mal!

lg Markus


```
class Zahlensystem {
    
    public static void main(String[] args) {
   
    int a= 100;
    
    while (a > 0) {
    
    System.out.print(a % 2);
    
    a=a/2;
    
    }
    
    System.out.println("");
    
    }
}
```


----------



## SlaterB (24. Aug 2008)

schwer ist das nicht,
sammle die Chars oder Zahlen in einem String/ Array oder Liste 
und verwende eine for-Schleife, die hinten beginnt


----------



## markus_cheers (24. Aug 2008)

Wenn du mir den Code reinschreiben würdest 
wär echt super...


----------



## Marco13 (24. Aug 2008)

Mit einer rekursiven Funktion könnte man das recht elegant machen. Im Pseudocode ungefähr so

```
static void toBin(int n)
{
    if (n==0) return;
    toBin(n/2);
    print(n%2);
}
```


----------



## markus_cheers (24. Aug 2008)

Eine void Methode hat doch kein return, oder?

Wär super wenn mir jemand den Computercode für mein
Problem reinschreiben könnte! Irgendwie funktioniert es nicht...


----------



## 0x7F800000 (24. Aug 2008)

so, versuchen wir mal die kolmogorow-komplexität dieser funktion unter der Nebenbedingung "Sprache=java" rauszufinden 

```
String f(int i){return i<=1?""+i:f(i/2)+i%2;}
```
Das sind 46 Zeichen. Wer bietet weniger?


----------



## markus_cheers (24. Aug 2008)

Marco13 hat gesagt.:
			
		

> Mit einer rekursiven Funktion könnte man das recht elegant machen. Im Pseudocode ungefähr so
> 
> ```
> static void toBin(int n)
> ...



Ich bekomme es irgendwie nicht hin!

Wenn mir jemand den Quellcode posten könnte wär ich echt 
begeistert!


----------



## Guest (24. Aug 2008)

DocRandom hat gesagt.:
			
		

> ```
> public String horner( int number, int base)throws IllegalNumberSystemException {
> 
> switch (base) {
> ...



Das Grundgerüst muß nicht unbedingt so aussehen, daß ich für 2 oder 8 eine extra Implementierung benötige.

die Berechnung unterscheidet sich ja nur dahingehend, daß ich durch die Basis( also 2, bzw. 8 ) teile.
Wenn ich die Basis der Methode mitgebe benötige ich keine verschiedenen Implementierungen.

Selbst bei einer Basis>10 müßte die Implementierung dahingehend erweitert werden, daß zahlen größer 9 in Buchstaben gewandelt werden.

Eine spätere Erweiterung auf andere Basen, z.B 6,7,4,5,3,9 wäre dann auch viel leichter zu bewerkstelligen.


----------



## Ariol (24. Aug 2008)

Hab mal nen sozialen Tag


```
public class Horner
{
	public static String berechne(int number, int base) throws IllegalNumberSystemException
	{
		if(base <= 1 || base > 36) // basis zu groß oder zu klein
		{
			throw new IllegalNumberSystemException(base);
		}
		
		StringBuilder sb = new StringBuilder();
		boolean negative = false;
		
		if(number < 0) //<-- negative Zahlen
		{
			number = -number;
			negative = true;
		}

		while (number >= 0) //<-- Null muss auch was ausgeben
		{
			int i = number % base;
			
			if (i < 10) //<-- Zahlen 0-9
			{
				sb.append(i);
			}
			else if(i < 36)//<-- Buchstaben a-z
			{
				char c = (char)(i+87);
				sb.append(c);
			}
			
			number /= base;
			
			if(number <= 0) //<-- Zum Beenden der Schleife 
			{
				number = -1;
			}
		}
		
		if(negative)//<-- negative
		{
			return sb.append('-').reverse().toString();
		}
		return sb.reverse().toString();	
	}

}
```


```
public class IllegalNumberSystemException extends Exception{

   /**
    * Constructs a new IllegalNumberSystemException
    *
    * @param e The wrong base
    */
   public IllegalNumberSystemException(int base) {
      super("Base \"" + base + "\" not valid!");
   }
}
```

EDIT: Hatte noch nen Fehler für a-z drin
EDIT2: Nochmal verbessert.


----------



## 0x7F800000 (25. Aug 2008)

@Ariol:
Das was du da tust ist kein Hornerschema. ist auch gut so. :toll:

@Gast [OP]:
Nachdem du dir die vorbildliche Lösung von Ariol angeschaut hast, tue folgendes: 
Sag deinem(r) Lehrer(in), dass er/sie nächstes Mal die Begriffe zumindest mal bei Wikipedia nachschlagen soll, bevor er/sie mit Fachwörtchen um sich schmeißt, deren Bedeutung er/sie nicht kennt. 

Mit Hornerschema kann man nichts in irgendein p-adisches System umrechnen. Bzw. man kann es natürlich, aber es ist ein völlig unnötiger performancekill. Hornerschema ist nur dann nützlich, wenn man als Erdbewohner auf dem Papier mit Buntstiften irgendetwas *ins Dezimale* zahlensystem umrechnen will. Das liegt einzig und alleine daran, dass man als Mensch das Kleine Einmaleins im dezimalsystem auswendiggelernt hat, und weil man das Hingeschriebene schnell modulo 10 rechnen gelernt hat, und daher weiß, wie groß der Übertrag bei der "zifferweisen" Addition ausfällt.

Für den Computer spielen solche psychologischen Faktoren absolut keine Rolle. Das einzige Zahlensystem mit dem er tatsächlich rechnen kann ist das binäre. Den Computer dazu zu zwingen, in jedem Berechnungsschritt alle zwischenergebnisse in ein Alien-mäßiges 13-adisches System umzurechnen ist wirklich nicht angebracht. 


@die verstörten leute die nichts besseres zu tun haben als sich das anzusehen...

Hab hier nochmal versucht, die Berechnung von der Zifferdarstellung zu trennen.
Das Programm ist übrigens voooll nützlich, ich musste auch schon mal in hausaufgaben irgendwas im Hexagesimalsystem darstellen 

```
public class P_Adic {
	
	// diese Klasse wandelt die einzelnen Zahlen in passende Ziffer um
	public static abstract class DigitWriter{
		protected StringBuilder builder;
		protected long base;
		
		public DigitWriter(long _base){
			base=_base;
			reset();
		}
		
		public void reset(){	builder=new StringBuilder();	}
		
		public abstract void addDigit(long n);
		public abstract String getResult();
	}
	
	/*verschiedene auspraegungen von DigitBuilder
	 * Es werden folgende Fallunterscheidungen gemacht:
	 * 2-7 oder 9-adisch:	4342156[7]  	(mit hinten drangehaengten basis)
	 * oktal:				0246775			(mit einer 0 vorne)
	 * dezimal:				199921376		(ganz normal)
	 * hexadezimal:			0x7F8AB3CD		(mit Buchstaben und 0x-Praefix)
	 * alles andere:		(34,23,57)[60] 	(geklammert & kommagetrennt & mit basis)
	 */
	public static class DecimalDigitWriter extends DigitWriter{
		public DecimalDigitWriter(long base){	super(base);	}
		public void addDigit(long n) 		{	builder.append(n);	}
		public String getResult() 			{	return builder.reverse().toString();	}
	}
	
	public static class OctalDigitWriter extends DecimalDigitWriter{
		public OctalDigitWriter(long base)	{	super(base);	}
		public String getResult()			{	return "0"+super.getResult();	}
	}
	
	public static class SmallDigitWriter extends DecimalDigitWriter{
		public SmallDigitWriter(long base)	{	super(base);	}
		public String getResult()			{	return super.getResult()+"["+base+"]";	}
	}
	
	public static class HexadecimalDigitWriter extends DigitWriter{
		public HexadecimalDigitWriter(long base){	super(base);	}
		public void addDigit(long d){	
			builder.append(
			new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}[(int)d]);
		}
		public String getResult(){	return "0x"+builder.reverse().toString();	}
	}
	
	public static class BigDigitWriter extends DigitWriter{
		private boolean firstDigit;
		public BigDigitWriter(long base){
			super(base);
			reset();
		}
		public void reset(){ super.reset(); firstDigit=true; }
		public void addDigit(long d) {
			if(firstDigit){
				firstDigit=false;
				builder.append(")"+new StringBuilder(""+d).reverse().toString());
			}else{
				builder.append(","+new StringBuilder(""+d).reverse().toString());
			}
			
		}
		public String getResult() {
			builder.append("(");
			return builder.reverse().toString()+"["+base+"]";
		}
	}
	
	// die eigentliche Funktion, die die p-adische darstellung einer Zahl liefert
	public static String p_Adic(long number, long base, DigitWriter w)
						throws IllegalArgumentException{
		// DigitWriter sind nicht statisch, da könnte was drin sein...
		w.reset();
		
		//unsinnige Basen ausschliessen
		if(base<2){
			throw new IllegalArgumentException("base="+base);
		}
		
		//vorzeichen merken
		boolean isNegative;
		number*=(isNegative=(number<0))?(-1):(1);
		
		//p-adische darstellung berechnen
		while(number>=base){
			w.addDigit(number%base);
			number/=base;
		}
		w.addDigit(number);
		
		//vorzeichen anpassen
		return isNegative?"-":""+w.getResult();
	}
	
	// eine einfachere variante, die vordefinierte DigitWriter waehlt
	public static String p_Adic(long number,long base) throws IllegalArgumentException{
		DigitWriter w;
		if(base==8){
			w=new OctalDigitWriter(base);
		}else if(base==10){
			w=new DecimalDigitWriter(base);
		}else if(base==16){
			w=new HexadecimalDigitWriter(base);
		}else if(base<10){
			w=new SmallDigitWriter(base);
		}else{
			w=new BigDigitWriter(base);
		}
		
		return p_Adic(number,base,w);
	}
	
	// TEST
	public static void main(String[] args) {
		
		long max_n=64;
		try{
			for(int n=0; n<=max_n; n++){
				System.out.println(n+"\t="+p_Adic(n,2)+
									 "\t\t="+p_Adic(n,8)+
									 "\t\t="+p_Adic(n,10)+
									 "\t\t="+p_Adic(n,16)+
									 "\t\t="+p_Adic(n,19)+
									 "\t\t="+p_Adic(n,60));
			}
		}catch(IllegalArgumentException e){
			System.out.println("Mehr Kaffee!!!");
		}
	
	}
}
```
fragt nicht wieso ich den Mist jetzt geschrieben hab... mir ist anscheinend langweilig  :roll: 
Naja, werd das schon irgendwo wieder gebrauchen können, eines tages...


----------



## florian1x (25. Aug 2008)

hab ausversehen doppelt gepostet   
naja sry hab einen beitrag hiermit kürzer editiert


----------



## florian1x (25. Aug 2008)

naja ich hab jetzt halt um 3.10 langeweile und helfe ma dem markus_cheers

also

*@ markus_cheers:*


```
public class Zahlensystem {
	
	/**
	 * wandelt den dezimalen Wert n in einen binären Wert um und gibt
	 * das Ergebnis direkt über die konsole aus
	 */
	static void toBin(int n)
	{
		if (n==0) return;
		toBin(n/2);
		System.out.print(n%2);
	}
	
	/**
	 * wandelt den dezimalen Wert n in einen binären Wert um und gibt
	 * das Ergebnis als String zurück
	 */
	static String toBinAsString(int n)
	{
		String bin = "";
		while(n != 0){
			n /= 2;
			bin += n%2;
		}
		return bin;
	}
	
	public static void main(String[] args) {
		int n = 10; // Die Zahl, die umgewandelt werden soll
		toBin(n); //Umwandlung mit Ausgabe über Konsole
		System.out.println();//Zeilenumbruch nach der ersten Ausgabe über Konsole
		String s = toBinAsString(n); //Umwandlung mit Speichern in einem String
		System.out.println(s); //Ausgabe des Strings über die Konsole
	}

}
```

Edit: 

hab ausversehen ganz unbewusst die zweite methode nicht rekursiv geschrieben hier das update geht aber beides 


```
/**
	 * wandelt den dezimalen Wert n in einen binären Wert um und gibt
	 * das Ergebnis als String zurück
	 */
	static String toBinAsString(int n)
	{
		
		String bin = "";
		if (n==0) return bin;
		toBin(n/2);
		return bin += n%2;
	}
```


----------



## 0x7F800000 (25. Aug 2008)

das geht natürlich noch kürzer   das mit "<=" durch "<" ersetzen ist zumindest mal offensichtlich....  :autsch: 

```
String f(int x){return (x<2?"":f(x/2))+x%2;}
```
So, das wären schon nur noch 44 Zeichen 


@florian1x:
Bei deinem Update hast du die fuktionen wohl irgendwie verwechselt oder wie?


----------



## Marco13 (25. Aug 2008)

43   

String f(int x){return(x<2?"":f(x/2))+x%2;}


----------



## 0x7F800000 (25. Aug 2008)

[die 34 hat er schnell wegeditiert der Bösewicht ] 
...Ja, da hast du Recht, zuviel whitespace *heul*


----------

