C# Zahlenraum Variabel machen ohne Kaskade

Xsp

Lt. Commander
Dabei seit
Jan. 2010
Beiträge
1.690
Hallo Community,

in der Schule machen wir grade ein Dezimal zu Binär Rechner.
Der ist ja eigentlich ganz easy, und den habe ich auch schon fertig.

Bei meinem Programm, darf man nur Zahlen in einem Raum bis zu 16Bit (65536 -1) eingeben.

Diesen Zahlenraum sollen wir nun Variabel machen, d.h. 2hoch8, 2hoch16, 2hoch24, 2hoch32...
Wir sollen es nur bis maximal 2hoch32 machen, da die größeren Zahlen so gut wie nie gebarucht werden.

Mein Lehrer hat es mit If/else gemacht, und wir sollen einen anderen Weg finden ohne If/else, switch/case. Also ohne Kaskaden.

Ich sitze nun schon geschlagene 3 Tage dran, eine Lösung zu finden. Ich komm aber auf keine. Vielleicht könnt ihr mir ein paar Lösung Ansetzte geben.

Ihr solltet mir nicht meine Hausaufgaben vorgaukeln, so lerne ich nichts, nur Ansätze wie ich es eventuell Lösen könnte.

Mein Programm läuft so zur Zeit:

Zahl: 12
umrechen in ein Binärzahl
Binärzahl umdrehen (weil das Programm die Zahl erst falsch herum in das Array schreibt)
Ergebnis: 0000|0000|0000|1010

Richtig:
Zahl: 12
[...]
Ergebnis: 1010

Wie man sieht, schmeißt der mir immer, die ganzen 16 Bit raus.
Das mit den Nullen abschneiden hatten wir auch schon. Nun sollen wir das ganze Variabel machen, sodass das Programm es praktisch Automatisch macht.
 

IggyK

Ensign
Dabei seit
Juli 2006
Beiträge
234
Hallo Xsp,

wie berechnest du denn aus einer Dezimalzahl eine Binärzahl? Teilst du immer durch 2 und schaust dir den Rest davon an? Arbeitest du dabei direkt auf einem Int oder auf einem String?

Könntest du deinen aktuellen (starren) Code hier posten? Dann würde es leichter Fallen, eine Lösung auszudenken, die sich an deine Denkweise anlehnt und deine Schwierigkeit mit der Aufgabe zu erkennen.

Viele Grüße
TSO
 

SC6

Cadet 4th Year
Dabei seit
Feb. 2008
Beiträge
77
Nimm while oder irgendeinen anderen loop (for?) und schmeiß solange alle 0-Elemente raus bis du das gewünschte Ergebnis hast.
 

timurinamanu

Lt. Junior Grade
Dabei seit
Apr. 2008
Beiträge
269
Ich weiss jetzt nicht ob ich dein Problem ganz verstanden ab aber ich glaub, dass du mit diesem Ansatz weiter kommst:

mach ne Funktion die sich selbst aufruft
etwa so:

int umrechner(hochzahl,zahl){

if(hochzahl<=32)
umrechner(hochzahl+1,zahl);

return zahl ^ hochzahl//halt je nach Syntax, ich glaub in C# ists Math.pow

}
 

Yuuri

Fleet Admiral
Dabei seit
Okt. 2010
Beiträge
12.629
Code:
String.TrimStart( new char[] { '0' } );
Wofür eine Schleife?
 

Xsp

Lt. Commander
Ersteller dieses Themas
Dabei seit
Jan. 2010
Beiträge
1.690
Nimm while oder irgendeinen anderen loop (for?) und schmeiß solange alle 0-Elemente raus bis du das gewünschte Ergebnis hast.
Genau das sollten wir ja auch nicht machen ;)

So weit sind meinem Programkenntnisse noch nicht. ;)

Das umrechnen zu Hexa, ist nur da weil ich Langeweile hatte.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using C = System.Console;
using Cv = System.Convert;

namespace HornerSchema
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] Binaer = new int[16];
            string[] Hexa = new string[] { "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F" };
            int[] Stellen = new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
            int intZahl, intZwischenspeicher, intHexa;
            string strwiederholen;
            bool bolfalscheZahl;

            bolfalscheZahl = false;
            intZwischenspeicher = 0;

            do
            {
                C.Clear();
                C.WriteLine("\t\t\t╔═══════════════════════════════╗");
                C.WriteLine("\t\t\t║                               ║");
                C.WriteLine("\t\t\t║            Dezi in            ║");
                C.WriteLine("\t\t\t║         Binär && Hexa         ║");
                C.WriteLine("\t\t\t║           umrechnen           ║");
                C.WriteLine("\t\t\t║                               ║");
                C.WriteLine("\t\t\t╚═══════════════════════════════╝");
                C.Write("\n\n\t___________________________________________________________________");
                C.Write("\n\n\t\tDieses Programm Rechnet Ihnen eine Dezimalzahl (Basis 10)\n\t\tin eine Binär- (Basis 2) und Hexadezimalzahl (Basis 16) um.");
                C.Write("\n\t___________________________________________________________________");

                do
                {
                    C.Write("\n\n\n\t\tGeben Sie eine Zahl ein: ");
                    intZahl = Cv.ToInt32(C.ReadLine());
                } while (intZahl < 0);
                
                if (intZahl > 65535)
                {
                    bolfalscheZahl = true;
                }
                else
                {
                    intZwischenspeicher = intZahl;
                    intHexa = intZahl;

                    for (int i = 0; i < 16; i++)
                    {
                        Binaer[i] = intZahl % 2;
                        intZahl /= 2;
                    }
                    for (int i = 0; i < 16; i++)
                    {
                        Stellen[i] = intHexa % 16;
                        intHexa /= 16;
                    }
                }
                if (bolfalscheZahl == true)
                {
                    C.Write("\n\t\tSie haben eine zu hohe Zahl eingegeben.\n\t\tDie Zahl darf maximal 16 Bit groß sein.");
                }
                else
                {
                    C.Write("\n\t___________________________________________________________________");
                    C.Write("\n\n\t\tDie Zahl die Sie eingegeben haben: {0}", intZwischenspeicher);
                    C.Write("\n\n\t\tBinär:");
                    C.Write("\n\n\t\t\t");
                    for (int i = 15; i >= 0; i--)
                    {
                        if (i == 3 || i == 7 || i == 11 || i == 15)
                        {
                            C.Write("|");
                        }
                        C.Write("" + Binaer[i]);
                    }
                    C.Write("|");
                    C.Write("\n\n\t\tHexa:");
                    C.Write("\n\n\t\t\t");
                    for (int i = 15; i >= 0; i--)
                    {
                        if (i == 3 || i == 7 || i == 11 || i == 15)
                        {
                            C.Write("|");
                        }
                        C.Write("" + Hexa[Stellen[i]]);
                    }
                    C.Write("|");
                }
                C.Write("\n\t___________________________________________________________________");
                C.Write("\n\n\n\t\tMöchten Sie das Programm wiederholen? (y|Y): ");
                strwiederholen = Cv.ToString(C.ReadLine());
            } while (strwiederholen == "y" || strwiederholen == "Y");
        }
    }
}

Danke, aber das ist ja ganz einfach mit einer For-Schleife.

Ich muss nur die Array Länge Variabel machen je nach Zahl die ich eingegeben habe.
 

[GP] mino

Lt. Commander
Dabei seit
März 2009
Beiträge
1.901
hier ein quick&dirty snippet aus c++ mit 32bit eingabe.

PHP:
qDebug() << value2BinString(20);
ergibt die ausgabe "10100". ist es das, was du suchst?

in C# sollte es gleich gehen, bin in C# nur schon etwas abgekühlt.

PHP:
QString value2BinString(int zahl)
{
	QString str = "";
	

	for (int i = 0; i < 32; i++) //string mit 0 oder 1 füllen
	{
		if (zahl & 1)
			str = '1' + str;
		else
			str = '0' + str;

		zahl = zahl >> 1;
	}

	//vorstehende nullen entfernen bis auf das letzte zeichen
	while ((str[0] == '0') && (str.size() > 1))
		str.remove(0, 1);
		

	return str;

}
 
Zuletzt bearbeitet:

DaZpoon

Commander
Dabei seit
Dez. 2009
Beiträge
2.155
der allgemeine ansatz wäre doch die anzahl der notwendigen bytes zur darstellung zu ermitteln. dazu teile man (die eingegebene zahl - 1) so lange durch 16, so lange diese (integer-)division ein ergebnis >= 1 ergibt.
eine division durch 16 entspricht binär übrigens dem schieben einer zahl nach rechts um 4 stellen. man schaut also ob immer noch irgendwo ein darzustellendes bit steht.
die (anzahl der zählungen +1) entspricht der anzahl bytes, wonach du deine ausgabe zurechtformatieren kannst.
 

timurinamanu

Lt. Junior Grade
Dabei seit
Apr. 2008
Beiträge
269
also dein Code scheint mir etws zu überdimensioniert und geht sicher einfacher zu schreiben, aber egal ich will deinen Code nicht kritisieren.

Folgendes könnte dir helfen:

Du kannst arrays bzw. listen mit Join(Trennzeichen) zu strings machen
also: [0,1,2,3].join(';') ergibt: "0;1;2;3"

und die nuller kannst raustun indem du zu int parst und wieder zurückparst, aber trim ist die schönere Variante
 

holy

Lieutenant
Dabei seit
Aug. 2008
Beiträge
533
Ich vermute mal, dein Lehrer möchte dir binäre Operatoren und Bit-Shifts beibringen.

Schau dir das mal an:

Operator & - Link
Operator | - Link
Operator << - Link
Operator >> - Link

Ich gebe dir einfach mal ein paar Beispiele.

Shifts:
2 hoch 16 = 2 << 15, oder 2 hoch 16 = 1 << 16
2 hoch 32 = 2 << 31, oder 2 hoch 32 = 1 << 32
3 hoch 32 != 3 << 31

Binär-Operatoren:
Code:
1 | 1 = 1   -   1 & 1 = 1
1 | 0 = 1   -   1 & 0 = 0
0 | 1 = 1   -   0 & 1 = 0
0 | 0 = 0   -   0 & 0 = 0
Wenn du jetzt brücksichtigst, dass Dezimalzahlen intern binär dargestellt werden, kannst du auch sowas machen

11 & 5 = 1

Obiges Beispiel mal etwas anders geschrieben

Code:
11 = 1011
 5 = 0101

        1011
&       0101
-------------
        0001
11 | 5 = 15, denn

Code:
        1011
|       0101
-------------
        1111
Verstanden? ;)


Das gleiche Prinzip (bzgl. binärer Darstellung) gilt natürlich auch für die Shifts

11 >> 1 = 5, denn

1011 um eine Stelle nach rechts geschoben ist 101

Etwas "bildlicher":

->1011
-------|

Rechts die 1 fällt einfach von der Kante runter und aus 1011 wird 101.
Wenn du nach links schiebst (<<), hängt man rechts aussen einfach eine null dran.

Bsp:

11 << 1 = 22

1011 << 1 = 10110

Im Spoiler siehst du, wie man so Dezimalzahlen in Binärzahlen umwandeln kann, ohne mit überschüssigen Nullen rumzuhantieren.
Code:
int dezimal = 11;
string binaer = string.Empty;
while ( dezimal != 0 )
{
    binaer = ( dezimal & 1 ) + binaer;
    dezimal = dezimal >> 1;
}

// binaer = 1011
Console.Out.WriteLine( binaer );

Hoffe es hilft dir weiter.

Edit, hoffe die Formatierung stimmt endlich mal :)
 
Zuletzt bearbeitet:

Xsp

Lt. Commander
Ersteller dieses Themas
Dabei seit
Jan. 2010
Beiträge
1.690
Hey,
danke für die ganzen Lösungsansetzte.

@holy
Danke für die super Erklärung, dass habe ich mir letztes Jahr auch schon angeguckt, aber das brauche ich nicht wirklich für die Aufgabe.

Aber dennoch habe ich heute wiedereinmal was dazugelernt ^^

Also ich glaube ich habe mich falsch ausgedrückt bei der Aufgabenstellung.

__________________________________________________
Bevor man irgendwas rechnet, umdreht, reinpackt etc. muss man die Bitlänge der Zahl schon ermitteln.

Mein Lehrer hatte es Ungefähr so:

Code:
if(intZahl < 256 && intZahl > -256)
{
     int[]ArrayLaenge = 8;
     int[]... = 7; 
}
else
{
     if(intZahl < 65536 && intZahl > -65536)
     {
          int[] ArrayLaenge = 16;
          ...
     }
     else
     {
           if(...)
           usw...
     }
}

Darüber war die Zahl Eingabe und mehr nicht. Keine Rechnungen etc.

PS: Aber dennoch danke für die Mühe die Ihr euch gemacht habt. Ihr habt heute einen kleinen aber alten Jungen (21 Jahre -.-*) wieder viel beigebracht. ;)

EDIT:
Ich kann noch nicht eigene Methoden, Funktionen etc schreiben. Ich beherrsche die Standartprogrammierung, die man so im ersten Jahr lernt.
- if/else
- switch-case
- Arrays
- for Schleifen
- do/while
 

[GP] mino

Lt. Commander
Dabei seit
März 2009
Beiträge
1.901
falls du eine funktion für die bestimmung der bitlänge brauchen solltest

Code:
int bestimmeBitlänge(int zahl)
{
	int letztes_bit = 1 << 31;
	int bit_verschiebungen = 0;

	while(!(zahl & letztes_bit || bit_verschiebungen == 31))
	{
		zahl = zahl << 1;
		bit_verschiebungen++;
	}
	
	return 32 - bit_verschiebungen;
}
 

Xsp

Lt. Commander
Ersteller dieses Themas
Dabei seit
Jan. 2010
Beiträge
1.690
Haaahaaaa...;)

Ich habe schon fast eine Lösung.
Mir fehlt aber noch die If-Bedingung.

Code:
do
{
     intCounter = 8;

     if(Bedingung die mir noch fehlt)
     {
          ArrayLaenge[intCounter] = intCounter;
          bolArray = true;
     }
     else
     {
          intCounter += 8;
          bolArray = false;
     }
}while(bolArray == true);
So sollte es klappen glaube ich. Nur die Bedingung (da muss der Zahlenraum irgenwie hin) fehlt noch.
 

[GP] mino

Lt. Commander
Dabei seit
März 2009
Beiträge
1.901
müsste diese abfage sein:
Code:
int bestimmteByteLänge(int zahl)
{
	if      (zahl & 0xFF000000) return 4;
	else if (zahl & 0x00FF0000) return 3;
	else if (zahl & 0x0000FF00) return 2;

	return 1;
}
 

Xsp

Lt. Commander
Ersteller dieses Themas
Dabei seit
Jan. 2010
Beiträge
1.690
müsste diese abfage sein:
Code:
int bestimmteByteLänge(int zahl)
{
if (zahl & 0xFF000000) return 4;
else if (zahl & 0x00FF0000) return 3;
else if (zahl & 0x0000FF00) return 2;

return 1;
}
Genau das ist mit Kaskade gemeint...kein if else if else if else ;)
Oder auch genannt verschachtelte if/else und auch keine if else hintereinander.
 

[GP] mino

Lt. Commander
Dabei seit
März 2009
Beiträge
1.901
tzz :)

Code:
int bestimmteByteLänge(int zahl)
{
	if (zahl == 0) return 1;

	int bytes = 4;

	while (!(zahl & 0xFF000000))
	{
		zahl = zahl << 8;
		bytes--;
	}

	return bytes;
}
 

Xsp

Lt. Commander
Ersteller dieses Themas
Dabei seit
Jan. 2010
Beiträge
1.690
Das ist eine neue Methode oder?

Ich kenne mich mit Methoden nicht aus.
Was ist den dieses
Code:
 return
?

0xFF00000 = Hexadezimal? Wenn ja warum?
Und was hat die Zeile zu bedeuten?


Heist das, dass bei "zahl" 8 Stellen hinzukommen?
 

derlolomat

Lieutenant
Dabei seit
Feb. 2011
Beiträge
796
Ein while ist doch ebenso eine Kaskade. Praktisch eine Schleife mit if/Abbruchbedingung. Dasselbe kann man allgemein für Schleifen sagen.

Ich würde zu gerne mal die "Lösung" des Lehrers wissen. Wahrscheinlich entweder über while oder über eine externe Methode von Java, die dann eh Kaskaden verwendet, ironischerweise.
 
Top