Java Zahlensysteme umwandeln (mit Komma/Vorzeichen)

Yumix

Lt. Commander
Registriert
Juni 2009
Beiträge
2.031
Hiho,

bin noch recht neu in Java und schreibe grad ein kleines Programm zur Umwandlung verschiedener Zahlensysteme (erstmal nur 2,8,10,16). Ist an sich ja relativ einfach mit Funktionen wie parseInt(x, n) und toBinaryString().

Mein Problem liegt jetzt bei negativen und Bruchzahlen. An sich weiss ich wie man sie per Hand umwandelt, meine Frage ist jetzt ob es dafür auch eine simplere, von Java bereits mitgelieferte Methode gibt oder muss ich das jetzt für jedes Zahlensystem von Hand machen?

Das Programm sieht zur Zeit so aus:
Code:
import java.awt.*;
import java.applet.*;
import java.awt.event.*;

//Variablen deklarieren
public class Umwandler extends Applet implements ActionListener {
	Label Titel, Resultat;
	Button Convert, Copy;
	TextField Eingabe;
	Choice Format;
	Checkbox Negative;

//Buttons und Textfelder erstellen und beschriften
	public void init (){
		
		Titel = new Label ("UMWANDLER",Label.CENTER);		
		Titel.setBackground(new java.awt.Color(255,255,128));
		Eingabe = new TextField("");
		Resultat = new Label ("Resultat",Label.CENTER);
		Resultat.setBackground(new java.awt.Color(255,255,255));
		
		Format = new Choice();
		Format.add("Dezimal -> Binär");
		Format.add("Dezimal -> Hexadezimal");
		Format.add("Dezimal -> Octal");
		Format.add("Binär -> Dezimal");
		Format.add("Binär -> Hexadezimal");
		Format.add("Binär -> Octal");
		Format.add("Hexadezimal -> Dezimal");
		Format.add("Hexadezimal -> Binär");
		Format.add("Hexadezimal -> Octal");
		Format.add("Octal -> Dezimal");
		Format.add("Octal -> Binär");
		Format.add("Octal -> Hexadezimal");
		
		Convert = new Button ("CONVERT");
		Convert.addActionListener(this);
		Copy = new Button ("copy result to textfield");
		Copy.addActionListener(this);
		
		Negative = new Checkbox("Negative Zahl?",null,false);
		
		setSize(200, 200);
		setLayout(new GridLayout(7, 1));
		add(Titel);
		add(Eingabe);
		add(Format);
		add(Negative);
		add(Convert);
		add(Resultat);
		add(Copy);
		
	}

	public void actionPerformed(ActionEvent z) {		
		if (z.getActionCommand() == "CONVERT") { 
			switch (Format.getSelectedIndex()){
			case 0:
				int dtb = Integer.valueOf(Eingabe.getText());
				String dtbStr = Integer.toBinaryString(dtb);
				Resultat.setText(dtbStr);
				break;
			case 1:
				int dth = Integer.valueOf(Eingabe.getText());
				String dthStr = Integer.toHexString(dth);
				Resultat.setText(dthStr);
				break;
			case 2:
				int dto = Integer.valueOf(Eingabe.getText());
				String dtoStr = Integer.toOctalString(dto);
				Resultat.setText(dtoStr);
				break;
			case 3: 
				int btd = Integer.parseInt(Eingabe.getText(), 2); 
				String btdStr = Integer.toString(btd);
				Resultat.setText(btdStr);
				break;
			case 4:
				int bth = Integer.parseInt(Eingabe.getText(), 2); 
				String bthStr = Integer.toHexString(bth);
				Resultat.setText(bthStr);
				break;
			case 5:
				int bto = Integer.parseInt(Eingabe.getText(), 2);
				String btoStr = Integer.toOctalString(bto);
				Resultat.setText(btoStr);
				break;
			case 6:
				int htd = Integer.parseInt(Eingabe.getText(), 16); 
				String htdStr = Integer.toString(htd);
				Resultat.setText(htdStr);
				break;
			case 7:
				int htb = Integer.parseInt(Eingabe.getText(), 16); 
				String htbStr = Integer.toBinaryString(htb);
				Resultat.setText(htbStr);
				break;
			case 8:
				int hto = Integer.parseInt(Eingabe.getText(), 16); 
				String htoStr = Integer.toOctalString(hto);
				Resultat.setText(htoStr);
				break; 
			case 9:
				int otd = Integer.parseInt(Eingabe.getText(), 8); 
				String otdStr = Integer.toString(otd);
				Resultat.setText(otdStr);
				break;
			case 10:
				int otb = Integer.parseInt(Eingabe.getText(), 8); 
				String otbStr = Integer.toBinaryString(otb);
				Resultat.setText(otbStr);
				break;
			case 11:
				int oth = Integer.parseInt(Eingabe.getText(), 8); 
				String othStr = Integer.toHexString(oth);
				Resultat.setText(othStr);
				break;
			default:
				break;
			}
		}
		else if (z.getActionCommand() == "copy result to textfield") {
			String copyresult = String.valueOf(Resultat.getText());
			Eingabe.setText(copyresult);
		}
	}	
}

Welcher Weg ist also am einfachsten?
Danke schonmal im Vorraus.
 
Puh äh mit Komma... das ist eigentlich in anderen Zahlensystemen als dem 10er nicht üblich, aber möglich. Kann mir aber nicht vorstellen, dass dafür schon was in den Standardbibliotheken dabei ist.
Schau dir einfach hier die Vorgehensweise beim Umrechnen an, und forme das in Java-Code ;-)
 
Danke schonmal für die Antwort. Kommazahlen kommen sicherlich in anderen Systemen nicht so oft vor, da ich sie aber öfters in meinem ersten Semester Microcontroller benutzt habe wollt ich sie halt mit reinnehmen. Mit float/double sollte das doch machbar sein oder?

Notfalls verzichte ich auch darauf, aber die negativen Zahlen sind mir schon wichtig. Von Dezimal nach Bin/Oct/Hex funzt das ja auch, bis auf die Tastsache, dass vorne alles mit 1 oder f aufgefüllt wird so dass man nicht mehr erkennt wo der Eigentliche Wert nun anfängt oder auch nicht. Umgekehrt oder funzt es aber natürlich nicht mehr, das Programm weiss ja nicht ob es jetzt eine negative Zahl ist oder nicht.
 
nenji.lu schrieb:
Umgekehrt oder funzt es aber natürlich nicht mehr, das Programm weiss ja nicht ob es jetzt eine negative Zahl ist oder nicht.

Doch geht auch, aber der Aufwand das zu implementieren ist wesentlich höher. Der Trick dabei ist es als Datentyp String zu verwenden. Wie wir alle wissen, hat ein String ebenfalls eine Indexierung wie ein Array. D.h. wenn eine negative Zahl eingegeben wird(Bedingung: das Minuszeichen vor der Zahl muss mit eingegeben werden), dann prüft man ob an String-Index[0] ein "-" steht, als ein char (geht auch über ASCI Tabelle mit int-Werten) und formt dementsprechend nach den Regeln um. Ich hatte das ganze mal für eine Stack-Infix-to-Postfix Auswertung geschrieben... Also wenn du Spass am Programmieren hast, dann leg los.. :)
 
In diesem Fall ist es eher eine Muss-Sache als Spaß am programmieren^^

Muss das dann also doch Step-by-Step machen.....
Hatte jetzt 'ne Checkbox eingebaut so dass man separat angeben muss ob es sich jetzt um eine negative Zahl handelt oder nicht. Denn das "-" wird ja nur im dezimalen System benutzt.
 
So, sieht jetzt folgendermaßen aus:

Code:
...
import java.lang.Math.*;
...
...
...
	public void actionPerformed(ActionEvent z) {		
		if (z.getActionCommand() == "CONVERT") { 
			boolean checked = Negative.getState();
			switch (Format.getSelectedIndex()){
			case 0:
				if (checked == true){
					int dtb = Math.abs(Integer.valueOf(Eingabe.getText()));
					Resultat.setText(getComplement(dtb));
				}
				else {
					int dtb = Integer.valueOf(Eingabe.getText());
					String dtbStr = Integer.toBinaryString(dtb);
					Resultat.setText(dtbStr);
				}
				break;
			case 1:
				if (checked == true){
					int dth = Math.abs(Integer.valueOf(Eingabe.getText()));
					String dthStr = Integer.toHexString(Integer.parseInt(getComplement(dth),2));
					Resultat.setText(dthStr);
				}
...
...
...
Methode für 2er Komplement
Code:
	public static String getComplement(int x){
		String ToComplement = Integer.toBinaryString(x);
		String Invert = ToComplement.replaceAll("0","x").replaceAll("1","0").replaceAll("x","1");
		
		int a = Integer.parseInt(Invert,2);
		int b = 1;
		int c = a + b;
		
		String Complement = Integer.toBinaryString(c);
		
		return Complement;
	}
Scheint so zu funktionieren. Nur noch für die 9 anderen Fälle einbauen dann sollten die Negativzahlen kein Problem mehr sein :)

edit: hmpf mist, klappt doch nicht 100% richtig -.-
 
Zuletzt bearbeitet:
Na ich hab den Fehler gemacht, dass ich teils 'ne negative Zahl in eine Positive umgewandelt habe, will jedoch für eine negative Nahl auch ein negatives Resultat. Außerdem habe ich vergessen die "1" als Vorzeichen mit hinzu zu geben. Also aus -10 wurde z.B. 0110 anstatt 10110. Wenn man das zurückwandelt kommt dann -2 anstatt -10 raus.

Gibt es eine Möglichkeit die Nullen immer alle mitzunehmen, also so, dass das Programm 0110 mitnimmt und nicht automatisch 110 ausspuckt?

edit: sieht zur Zeit so aus:
Code:
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.lang.Math.*;


//Variablen deklarieren
public class Umwandler extends Applet implements ActionListener {
	Label Titel, Resultat;
	Button Convert, Copy;
	TextField Eingabe;
	Choice Format;
	Checkbox Negative;

//Buttons und Textfelder erstellen und beschriften
	public void init (){
		
		Titel = new Label ("UMWANDLER",Label.CENTER);		
		Titel.setBackground(new java.awt.Color(255,255,128));
		Eingabe = new TextField("");
		Resultat = new Label ("Resultat",Label.CENTER);
		Resultat.setBackground(new java.awt.Color(255,255,255));
		
		Format = new Choice();
		Format.add("Dezimal -> Binär");				//dtb
		Format.add("Dezimal -> Hexadezimal");		        //dth
		Format.add("Dezimal -> Octal");				//dto
		Format.add("Binär -> Dezimal");				//btd
		Format.add("Binär -> Hexadezimal");			//bth
		Format.add("Binär -> Octal");				//bto
		Format.add("Hexadezimal -> Dezimal");		        //htd
		Format.add("Hexadezimal -> Binär");			//htb
		Format.add("Hexadezimal -> Octal");			//hto
		Format.add("Octal -> Dezimal");				//otd
		Format.add("Octal -> Binär");				//otb
		Format.add("Octal -> Hexadezimal");			//oth
		
		Convert = new Button ("CONVERT");
		Convert.addActionListener(this);
		Copy = new Button ("copy result to textfield");
		Copy.addActionListener(this);
				
		Negative = new Checkbox("Negative Zahl?",null,false);
		
		setSize(200, 200);
		setLayout(new GridLayout(7, 1));
		add(Titel);
		add(Eingabe);
		add(Format);
		add(Negative);
		add(Convert);
		add(Resultat);
		add(Copy);
		
	}

	public void actionPerformed(ActionEvent z) {		
		if (z.getActionCommand() == "CONVERT") { 
			boolean checked = Negative.getState();
			switch (Format.getSelectedIndex()){
			case 0:
				if (checked == true){
					int dtb = Math.abs(Integer.valueOf(Eingabe.getText()));
					Resultat.setText(getComplement(dtb));
				}
				else {
					int dtb = Integer.valueOf(Eingabe.getText());
					String dtbStr = Integer.toBinaryString(dtb);
					Resultat.setText(dtbStr);
				}
				break;
			case 1:
				if (checked == true){
					int dth = Math.abs(Integer.valueOf(Eingabe.getText()));
					String dthStr = Integer.toHexString(Integer.parseInt(getComplement(dth), 2));
					Resultat.setText(dthStr);
				}
				else {
					int dth = Integer.valueOf(Eingabe.getText());
					String dthStr = Integer.toHexString(dth);
					Resultat.setText(dthStr);
				}
				break;
			case 2:
				if (checked == true){
					int dto = Math.abs(Integer.valueOf(Eingabe.getText()));
					String dtoStr = Integer.toOctalString(Integer.parseInt(getComplement(dto), 2));
					Resultat.setText(dtoStr);
				}
				else {
					int dto = Integer.valueOf(Eingabe.getText());
					String dtoStr = Integer.toOctalString(dto);
					Resultat.setText(dtoStr);
				}
				break;
			case 3: 
				if (checked == true){
					int btd = Integer.valueOf(Eingabe.getText(), 2);
					String btdStr = Integer.toString(Integer.parseInt(getComplement(btd), 2));
					Resultat.setText("-" +btdStr);
				}
				else {
					int btd = Integer.parseInt(Eingabe.getText(), 2); 
					String btdStr = Integer.toString(btd);
					Resultat.setText(btdStr);
				}
				break;
			case 4:
				if (checked == true){
					int bth = Integer.valueOf(Eingabe.getText(), 2);
					String bthStr = Integer.toHexString(bth);
					Resultat.setText(bthStr);
				}
				else {
					int bth = Integer.parseInt(Eingabe.getText(), 2); 
					String bthStr = Integer.toHexString(bth);
					Resultat.setText(bthStr);
				}
				break;
			case 5:
				if (checked == true){
					int bto = Integer.valueOf(Eingabe.getText(), 2);
					String btoStr = Integer.toOctalString(bto);
					Resultat.setText(btoStr);
				}
				else {
					int bto = Integer.parseInt(Eingabe.getText(), 2);
					String btoStr = Integer.toOctalString(bto);
					Resultat.setText(btoStr);
				}
				break;
			case 6:
				if (checked == true){
					int htd = Integer.valueOf(Eingabe.getText(), 16);
					String htdStr = Integer.toString(Integer.parseInt(getComplement(htd), 2));
					Resultat.setText("-" +htdStr);
				}
				else {
					int htd = Integer.parseInt(Eingabe.getText(), 16); 
					String htdStr = Integer.toString(htd);
					Resultat.setText(htdStr);
				}
				break;
			case 7:
				if (checked == true){
					int htb = Integer.valueOf(Eingabe.getText(), 16);
					String htbStr = Integer.toBinaryString(htb);
					Resultat.setText(htbStr);
				}
				else {
					int htb = Integer.parseInt(Eingabe.getText(), 16); 
					String htbStr = Integer.toBinaryString(htb);
					Resultat.setText(htbStr);
				}
				break;
			case 8:
				if (checked == true){
					int hto = Integer.valueOf(Eingabe.getText(), 16);
					String htoStr = Integer.toOctalString(hto);
					Resultat.setText(htoStr);
				}
				else {
					int hto = Integer.parseInt(Eingabe.getText(), 16); 
					String htoStr = Integer.toOctalString(hto);
					Resultat.setText(htoStr);
				}
				break; 
			case 9:
				if (checked == true){
					int otd = Integer.valueOf(Eingabe.getText(), 8);
					String otdStr = Integer.toString(Integer.parseInt(getComplement(otd), 2));
					Resultat.setText("-" +otdStr);
				}
				else {
					int otd = Integer.parseInt(Eingabe.getText(), 8); 
					String otdStr = Integer.toString(otd);
					Resultat.setText(otdStr);
				}
				break;
			case 10:
				if (checked == true){
					int otb = Integer.valueOf(Eingabe.getText(), 8);
					String otbStr = Integer.toBinaryString(otb);
					Resultat.setText(otbStr);
				}
				else {
					int otb = Integer.parseInt(Eingabe.getText(), 8); 
					String otbStr = Integer.toBinaryString(otb);
					Resultat.setText(otbStr);
				}
				break;
			case 11:
				if (checked == true){
					int oth = Integer.valueOf(Eingabe.getText(), 8);
					String othStr = Integer.toHexString(oth);
					Resultat.setText(othStr);
				}
				else {
					int oth = Integer.parseInt(Eingabe.getText(), 8); 
					String othStr = Integer.toHexString(oth);
					Resultat.setText(othStr);
				}
				break;
			default:
				break;
			}
		}
		else if (z.getActionCommand() == "copy result to textfield") {
			String copyresult = String.valueOf(Resultat.getText());
			Eingabe.setText(copyresult);
		}
	}	
	
	public static String getComplement(int x){
		String ToComplement = Integer.toBinaryString(x);
		String Invert = ToComplement.replaceAll("0","x").replaceAll("1","0").replaceAll("x","1");
		
		int a = Integer.parseInt(Invert,2);
		int b = 1;
		int c = a + b;
		
		String Complement = Integer.toBinaryString(c);
		
		return Complement;
	}
}
Bei case 4,5,7,8,10,11 sind die ifelse Anweisungen noch gleich, hat sich erst nachträglich so ergeben als ich alles in negative Ergebnisse geändert habe.
 
Zuletzt bearbeitet:
Gibt es eine Möglichkeit die Nullen immer alle mitzunehmen, also so, dass das Programm 0110 mitnimmt und nicht automatisch 110 ausspuckt?

Kenne leiders keine Möglichkeit. Aber du könntest einfach mit Nullen auffüllen und etwas formatieren:
PHP:
else {
					int dtb = Integer.parseInt(Eingabe.getText());
					StringBuffer dtbStr = new StringBuffer(Integer.toBinaryString(dtb)); 
					// Erstes "Nibble" mit Nullen auffüllen
					try{
						dtbStr = dtbStr.insert(0, "000",0,4-(dtbStr.length()%4));
					}
					catch (IndexOutOfBoundsException e){
						// String Länge durch 4 teilbar
					}
					
					// "Nibble" mit Leerschlag formatieren
					int i = 4;
					int ii = 0;
					while(i < dtbStr.length()-ii){
						dtbStr = dtbStr.insert(i+ii," ");
						i+=4;
						ii+=1;
					}
					Resultat.setText(dtbStr.toString());
				}
				break;

Mir ist aufgefallen das bei Zahlen mit mehr als 9 Stellen eine NumberFormatExeption ausgelöst wird...
 
Vielen Dank, werd ich mir nachher mal anschauen.
 
Zurück
Oben