Beliebige dezimale Eingaben in die Basis 2^32 umwandeln


  • Mod

    Mach die Länge deines BigIntegers am besten variabel. Das brauchst du ohnehin, um + und * zu implementieren. Und wenn du dann + und * hast, kannst du damit Stellenwertsysteme umrechnen.

    Merke: Versuche nicht für jede Aufgabenstellung komplett alles neu zu schreiben, sondern zerlege Probleme in einfache Teilschritte (hier + und 😉 und mach diese so universell wie möglich (hier: + und * passen variabel die Länge an). Dann kannst du alle höheren Aufgabenstellungen aus den kleinen Teilen ganz einfach zusammensetzen.
    Außerdem hast du viel weniger, viel einfacher wartbaren Code. Und Optimierungen an den Teilschritten verbessern auch gleich alle höheren Algorithmen.



  • Also die Länge herausfinden ist kein Problem 😉
    Mein Problem ist folgendes:
    Ich habe eine beliebige Eingabe zur Basis 10 und möchte das gerne zur Basis 4294967296(2^32) umwandeln. Sofern meine Eingabe zur Basis 16 war, kann ich einfach 8 Stellen der Eingabe als eine Stelle des BigInts interpretieren.

    Es geht nur um die Umwandlung von der Basis 10 in die Basis 2^32

    Edit: Es muss genau sein. Hoffe, jeder weiß jetzt, was mein Problem ist. Ich habe alleine eine Woche gebraucht um überhaupt mein Problem zu finden 😃


  • Mod

    TobiasK schrieb:

    Immernoch das gleiche wundervolle Projekt für die Uni.

    TobiasK schrieb:

    Es geht nur um die Umwandlung von der Basis 10 in die Basis 2^32

    Das ist doch wohl nicht dein Ernst, oder? Mathematik, siebte Klasse?

    http://de.wikipedia.org/wiki/Stellenwertsystem



  • TobiasK schrieb:

    Es geht nur um die Umwandlung von der Basis 10 in die Basis 2^32

    Das machst Du ganz normal. Stör Dich einfach nicht am Typ BigInt. Ist nichts anderes als long oder double.

    BigInt mbi(char const* str){
      BigInt x=0;
      while(str!='\0')
        x=x*10+BigInt(*str-'0');
      return x;
    }
    

    Upps, kein C++-Land hier. Also ohne Operatorüberladung und zum Jux this als Bezeichner nehmen.

    void mbi(struct BigInt* this,char const* str){
      bigIntLoadZero(this);
      while(str!='\0'){
        bigIntMulInt(this,10);
        bigIntAddInt(this,*str-'0');
      }
    }
    


  • SeppJ schrieb:

    TobiasK schrieb:

    Immernoch das gleiche wundervolle Projekt für die Uni.

    TobiasK schrieb:

    Es geht nur um die Umwandlung von der Basis 10 in die Basis 2^32

    Das ist doch wohl nicht dein Ernst, oder? Mathematik, siebte Klasse?

    http://de.wikipedia.org/wiki/Stellenwertsystem

    Bitte lesen, dann schreiben.
    Schau dir mal mul-giant-a.txt und mul-giant-b.txt an und nenne mir einen Datentyp in C, mit denen ich dei Eingaben nach Wikipedia verarbeiten kann. Ich habe doch nur maximal den Typ ull 😉

    http://www.cn.uni-duesseldorf.de/teaching/sose10/info2/tests.zip

    volkard schrieb:

    TobiasK schrieb:

    Es geht nur um die Umwandlung von der Basis 10 in die Basis 2^32

    Upps, kein C++-Land hier. Also ohne Operatorüberladung und zum Jux this als Bezeichner nehmen.

    void mbi(struct BigInt* this,char const* str){
      bigIntLoadZero(this);
      while(str!='\0'){
        bigIntMulInt(this,10);
        bigIntAddInt(this,*str-'0');
      }
    }
    

    Das würde voraussetzen, dass die Multiplikation und Addition schon geschrieben ist, wenn ich dich richtig verstehe? 😕
    Boah Leute ist das nen Scheiß 😃 Stehe aber irgendwie immernoch auf dem Schlauch.
    Sofern ich als Eingabe eine Textdatei habe, kann ich die doch mit fgetc nur zeichenweise einlesen. Und wie ich von dem Schritt zur Basis 2^32 komme, ist mir leider unklar. Ich weiß leider nicht, was deine Methoden bigIntMulInt und bigIntAddInt genau bewirken. Bzw. wie ich dann den BigInteger aufbaue, da ich doch jedes Wort einzeln anspreche (s.o. der struct).

    Bitte nicht direkt auf mich drauf haun 🙄



  • TobiasK schrieb:

    Das würde voraussetzen, dass die Multiplikation und Addition schon geschrieben ist, wenn ich dich richtig verstehe? 😕

    Ja! Das ist genau das, was SeppJ in seinem ersten Posting von Dir wollte.
    Und genau dafür gibt's die Hex-Version, damit Du erstmal * und + testen kannst.

    Sofern ich als Eingabe eine Textdatei habe, kann ich die doch mit fgetc nur zeichenweise
    einlesen.

    Ja. Ich hab halt einen string gelesen und dann den int mbi (steht für macheBigInteger) den string ausgelesen.

    Und wie ich von dem Schritt zur Basis 2^32 komme, ist mir leider unklar.

    Die Basis ist integralser Bestandteil der BigInteger-Typs.

    Ich weiß leider nicht, was deine Methoden bigIntMulInt und bigIntAddInt genau bewirken. Bzw. wie ich dann den BigInteger aufbaue, da ich doch jedes Wort einzeln anspreche (s.o. der struct).

    Ach, der ist nur

    struct BigInt{
      unsigned int* ziffern;
      int ziffernAnzahl;
    };
    

    oder sowas. In den Funktionen greifst Du dann schon brav auf das ziffern-Array zu. Dadurch, daß die ziffernAnzahl auch da ist, können so Zahlen bei Bedarf wachsen (umkopieren in größeres Array und kleineres löschen oder realloc). Das wollte SeppJ auch haben.

    Bitte nicht direkt auf mich drauf haun 🙄

    Mal schauen, ob sich der Drang lange genug unterdrücken läßt.



  • Neben dem schon genannten Artikel hier im C++ Forum bieten sich auch an:

    https://mattmccutchen.net/bigint/index.html C++ / PD
    http://gmplib.org/ C+Asm / GNU LGPL
    https://www.openssl.org/docs/crypto/bn.html C / Free
    http://msdn.microsoft.com/en-us/library/aa387677%28v=VS.85%29.aspx C / nur Windows
    http://www.cryptopp.com/docs/ref/class_hex_encoder.html C++ / Free
    http://www.codeproject.com/KB/cpp/largenumber.aspx C+++STL / MS-PL
    http://shygypsy.com/tools/ C++ / Free
    http://codepad.org/t84OokJn C / GPL

    Insbesondere der 1. und der letzte sollten sich wohl leicht an deine Ansprüche anpassen lassen.



  • Morgen Jungs,

    mittlerweile habe ich:

    void mbi(struct BigInt* this,char const* str){
      bigIntLoadZero(this);
      while(str!='\0'){
        bigIntMulInt(this,10);
        bigIntAddInt(this,*str-'0');
      }
    }
    

    verstanden 😛 Ich müsste sogar nur aus meinem Array auslesen, da ich dort schon jede dezimale Ziffer passend drin habe. Umwandlungen sollten wie folgt aussehen (vorausgesetzt meine Methoden sind richtig :D)

    DEZ <- BIGINT

    int array[length];
    j=0;
    for ( i=0; i<length; i++) {
    	array[i] = bi.words[j]%10;
    	bi.words[j] /= 10;
    	if ( bi.words[j]/10 == 0 ){
    		array[i] = bi.words[j];
    		j++;
    	}
    }
    for ( i=length-1; i>=0; i--) {
    	fprintf(data, "%i",array[i]);
    }
    

    BIGINT <- DEZ

    bi.n = 1;
    bi.words = realloc (bi.words, sizeof(uint32) ) ;
    if (bi.words == NULL){
    	printf ( "\tERROR: while allocating memory\n" );
    	exit(1);
    }
    for ( i=length-1; i>=0; i--){
    	bi.words = multiply (bi.words, 10);
    	bi.words = add (bi.words, array[i]);
    }
    

    Es versteht sich von alleine das am höchsten Indiz im Array das MSB steht. Mal schauen, ob das alles rund laufen wird 🙂 oder ob ich vor dem rof heulen muss 😃



  • TobiasK schrieb:

    DEZ -> BIGINT

    int array[length];
    j=0;
    for ( i=0; i<length; i++) {
    	array[i] = bi.words[j]%10;
    	bi.words[j] /= 10;
    	if ( bi.words[j]/10 == 0 ){
    		array[i] = bi.words[j];
    		j++;
    	}
    }
    for ( i=length-1; i>=0; i--) {
    	fprintf(data, "%i",array[i]);
    }
    

    Du zerstörst hier den Inhalt der words.
    Ich kenne die Definition von bi nicht, aber gelten muss: sizeof(int)==sizeof(bi.words[0]). Ein eventuelles Vorzeichen müsstest du auch noch irgendwie berücksichtigen? Statt %i würde ich auch %d nehmen.

    TobiasK schrieb:

    BIGINT -> DEZ

    bi.words = realloc (bi.words, sizeof(uint32) ) ;
    

    Das müsste wohl heissen:

    bi.words = realloc (bi.words, length*sizeof(uint32) ) ;
    

    bzw. robuster:

    bi.words = realloc (bi.words, length*sizeof*bi.words ) ;
    


  • Vorzeichen muss nicht beachtet werden. Des weiteren gilt:

    typedef unsigned int uint32;
    typedef struct {
        uint32 n;
        uint32* words;
    } BigInt;
    

    Daraus folgt:

    Ich kenne die Definition von bi nicht, aber gelten muss: sizeof(uint32)==sizeof(bi.words[0])

    bzw. wir können auch direkt sizeof(4) schreiben.

    Frage:
    Wieso den Platzhalter %d und nicht %i? Habe kurz gegoogelt und finde nichts. Galileo Computing gibt auch nur Beide an, ohne Erklärungen 😕


Anmelden zum Antworten