Algorithmus Binär zu Decimal(string)



  • Hallo,
    Ich habe ein Problem, welches sich mit dem umwandeln von Binär zu Decimal beschäftigt. Normalerweise ist dies natürlich kein Problem.

    Hier ein kleines Beispiel:

    unsigned char* bin = new unsigned char[2];
    bin[0] = 93; // 01011101
    bin[1] = 32; // 00100000
    // Insgesamt ist es also binär 0101110100100000 oder decimal 23840
    int erg = 0;
    for(int i = 0; i < sizeof(bin) * 8; i++)
    {
        unsigned char byte = bin[i % 8];
        byte <<= 7 - i / 8;
        byte >>= 7;
    
        if (byte > 0)
            erg += pow(2, i);
    }
    

    Hier wird das Ergebnis in "erg" zwischengespeichert und kann dann ausgegeben werden. Bei 2 Byte ist das noch möglich allerdings ist die Größe von int ja begrenzt. Wie also das Ergebnis direkt in Textform bringen?

    Habe mir bereits ein paar Gedanken gemacht und mir ist nichts eingefallen. Googeln brachte auch nichts. Hoffe ihr könnt mir ein paar Denkanstösse geben.

    MFG
    Catalamo



  • long int (oder long long int ). Wenn es beliebig groß werden soll, dann musst du eine Lib für Big Integers benutzen, z.B. aus Boost.Multiprecision oder GMP (oder selbst etwas implementieren).

    Da die niedrigste Stelle der Dezimalzahl von jeder Stelle der Binärzahl abhängig ist, kannst du das nicht aufspalten.



  • Ich bin grade dabei zu versuchen etwas selbst zu implementieren. In den Libs für Big Integers muss das Problem welches ich habe ja auch irgendwie gelöst worden sein.

    Das einzige was mir noch einfällt wäre die Zahl nicht in einem byte(unsigned char) Array zu speichern sondern in einem string und dann damit rechnen. Aber das wäre ja ziemlich ineffizient. Alleine weil man pro Ziffer 1 byte bräuchte.

    MFG
    Catalamo



  • Catalamo schrieb:

    Ich bin grade dabei zu versuchen etwas selbst zu implementieren. In den Libs für Big Integers muss das Problem welches ich habe ja auch irgendwie gelöst worden sein.

    Ja, die haben das Problem auch gelöst. Dafür haben sie auch einiges an Aufwand gebraucht und inzwischen sind die Libs gut getestet.

    Als Ansatz vielleicht: Benutz intern einen vector<uint32_t> . Dann hast du quasi pro "Stelle" 2322^{32} Werte statt wie im Binärsystem 2 oder im Dezimalsystem 10. Du musst natürlich bei den Rechen-Operatoren auf Über- und Unterläufe achten.



  • Cool, daran habe ich garnicht gedacht 👍 🙂


  • Mod

    Ganz falscher Ansatz. Binär und Dezimal sind Darstellungen. Also Reihen von Ziffern. Wieso speicherst du Reihen von Ziffern in Form eines Zahlenwerts, der dann als Dezimaldarstellung interpretiert wieder diese Ziffernreihe ergibt? Erstens zeigt das, dass du nicht verstanden hast, wie Zahlen und Zahldarstellungen funktionieren* und zweitens machst du dir Arbeit dann doch doppelt. Einmal hier und dann noch einmal bei der Ausgabe (Rate mal, wie die Ausgabe von Zahlen funktioniert!). Also korrekte Datenstruktur wählen und das Ergebnis als Ziffernreihe speichern. Nicht nur entfallen dann automatisch alle deine Probleme, nach denen du hier fragst, es lösen sich sogar noch ganz automatisch andere Probleme, auf die du noch gar nicht gestoßen bist. Zum Beispiel: Was tun im Falle von Zahlensystemen mit einer Basis > 10? Bei dir unmöglich, mit den passenden Datenstrukturen hingegen trivial.

    *: Das ist Grundschulstoff! Leider vergessen es die meisten Leute wieder 😞 . Das ist das mit den "Einsern", "Zehnern", "Hundertern", usw.



  • SeppJ schrieb:

    Das ist Grundschulstoff! Leider vergessen es die meisten Leute wieder 😞 . Das ist das mit den "Einsern", "Zehnern", "Hundertern", usw.

    Hm..naja, käme auch auf die Grundschule an...
    An ein wenig Spielerei mit Carryflags (doppeldeutig) und/oder Hex/Binär/Octal-Umwandlungen oder Filo/Lifo o.ä. kann ich mich jedenfalls nicht erinnern.
    (An Divisionsaufgaben mit Binärwerten auch nicht so recht. Aber wir hatten Mengenlehre und Addition/Multiplikation von großen (gepackten) Zahlen per Hand. Aber auch nur Dezimal, nicht Binär, das ist schon ein kleiner Unterschied) 😉
    (Aber ich erinnere mich daran, dass man durcheinander kommen kann...)

    Da die Anzahl der Binärwerte nicht so groß ist, könnte man auch mit Tabellen und Adressarithmetik herummachen.

    Bei den heutigen 64Bit Registern (Intel PC) lassen im typischen Verbund u.a. die beiden Register (R)DX:(R)AX mit Rest in (R)DX zusammenschalten. Man kann hier also erstmal die Reste von 128 Bit breiten Zahlen nutzen (d.h. direkt ausdrucken).
    Mit den neueren größeren Registern kann man auch ganz gut rechnen, aber auf Hochsprachenebene dann halt mit der (hoffentlich) passenden Library dafür). Die Prozessoren haben selbst auch Optimierungen für dies und das. Hier könnt man mal gucken, was es (für den Zielprozessor/Prozessorgruppe) gibt, und was als Bib-Funktion verfügbar ist.
    Oder man macht sich einen Spaß, und rechnet alles mit 8 Bit - oder gar mit 4 Bit, vielleicht langsam, aber mit sympathischer Übersicht 😉


Anmelden zum Antworten