Größenordnung einer Long Long Zahl



  • hey leute, ich hab folgendes problem:

    wir sollen eine klasse schreiben, mit der wir überläufe der primitiven datentypen verhindern können. soweit so gut, dazu muss ich an einer stelle einen konstruktor bauen, der long-long in meine klasse Natuerlich umwandelt.

    alles klappt wunderbar, nur ab einer gewissen größenordnung der long long zahl spuckt mir der konstruktor nur noch mist aus...

    hier mein code:
    _nZiffer und _ziffer sind hierbei die attribute des objekts aus der klasse Natuerlich. ( _nZiffer gibt die länge des arrays an, _ziffer ist das array selbst)

    Natuerlich::Natuerlich ( long long zahl )
    {
    	_nZiffer = log10( double(zahl) ) + 1 ; // Könnte hier vielleicht der Fehler liegen?
    	_ziffer = new int[ _nZiffer ] ;
    	int pot = 10 ;
    	for ( int i = 0 ; i < _nZiffer ; ++i )
    	{
    		_ziffer[ i ] = int ( ( zahl % pot ) / ( pot / 10 ) ) ;
    		zahl = zahl - ( zahl % pot ) ;
    		pot *= 10 ;
    	}
    
    }
    

    danke schon mal... bin echt am verzweifeln...


  • Mod

    Was heißt "spuckt Mist mist aus"? Was ist eine "gewisse Größenordnung größenordnung"? Lies bitte mal den ersten Link in meiner Signatur, wie du Fragen stellst, die man auch beantworten kann.

    Zu deiner Gesamtidee fällt mir ein:

    Mr. Spock schrieb:

    Er ist intelligent, aber nicht erfahren. Seine Struktur deutet auf zweidimensionales dezimales Denken hin. Außerdem ist seine Shift-Taste kaputt.



  • Vorschlag für den VollNoob:

    #include <cassert>
    #include <vector>
    
    const int basis = 10000;     // Vier Dezimal-Ziffern
    typedef short stellentyp;    // pro short
    
    class Natuerlich
    {
      std::vector<stellentyp> stellen; // zahl = \sum_k basis^k * stellen[k]
    public:
      Natuerlich() {}
      Natuerlich(long z);
      :::
    };
    
    Natuerlich::Natuerlich(long z)
    {
      assert(z>=0); 
      while (z>0) {
        stellen.push_back(z % basis);
        z /= basis;
      }
    }
    
    • Selbstdefinierter Kopierkonstruktor ist nicht nötig (dank vector<>)
    • Selbstdefinierter Zuweisungsoperator ist nicht nötig (dank vector<>)
    • Selbstdefinierter Destruktor ist nicht nötig (dank vector<>)


  • ohh... vielen dank, aber ich fürchte, ich werde das nicht verwenden können... wir hatten beispielsweise <vector> noch gar nicht, also kann ich das erstens nicht ganz nachvollziehen und zweitens wird mein dozent da streiken
    dennoch vielen dank 🙂

    @ SeppJ: sorry, hast recht 🙂
    um es zu konkretisieren:
    mein konstruktor wandelt die zahlen der größenordnung 10^6 perfekt um, beim input von 10^9 wird aus 1 Milliarde plötzlich 7 Milliarden... und beim input der größenordnung 10^12 scheint es zum überlauf zu kommen, da der konstruktor gibt dann folgendes aus: 8-931000000000

    ich kann den fehler halt auch absolut nicht nachvollziehen... 😕


  • Mod

    Zeig mal konkreten Code, mit dem man den Fehler reproduzieren kann.

    Lies bitte auch mal den ersten Link in meiner..... Moment! Das habe ich dir doch schon gesagt! Scheint nicht viel genutzt zu haben 😡 .



  • Nochmals sorry, SeppJ, aber ich weiß grad leider nicht, was ich falsch mache.
    Ich bin doch um eine vernünftige und klare Sprache bemüht. Die Zeichensetzung stimmt auch und die Groß- und Kleinschreibung stört meiner Meinung nach nun nicht den Lesefluss, aber ok.

    Falls du meinst, dass ich so unflexibel in meiner Lösung bin und den Vorschlag von krümelkacker nicht annehme, dann muss ich zu meiner Verteidigung sagen, dass ich leider an die Inhalte meiner Vorlesung gebunden bin. Es ist bestimmt unschön, sich in so merkwürdige Gebilde reinzudenken, aber ich habe Verständnis, falls ihr darauf keine Lust habt.

    Wie auch immer.

    Hier nochmals der Code für den Konstruktor.
    Dieser steht in der Header-Datei.

    // Umwandlungskonstruktor von long long
    Natuerlich::Natuerlich ( long long zahl )
    {
    	_nZiffer = log10( double(zahl) ) + 1 ;
    	_ziffer = new int[ _nZiffer ] ;
    	int pot = 10 ;
    	for ( int i = 0 ; i < _nZiffer ; ++i )
    	{
    		_ziffer[ i ] = int ( ( zahl % pot ) / ( pot / 10 ) ) ;
    		zahl = zahl - ( zahl % pot ) ;
    		pot *= 10 ;
    	}
    
    }
    

    Und hier das Programm-Schnipsel aus der Main-Datei:

    long long test1 ;
    	cout << " obj1 (long long)	: " ;
    	cin >> test1 ;
    	Natuerlich obj1 ( test1 ) ;
    	cout << " Nach Konstruktor	: " << obj1 << " ; " << obj1.laenge() << endl << endl ;
    

    Ich hoffe, mein Problem ist soweit nachvollziehbar.



  • VollNoob schrieb:

    Nochmals sorry, SeppJ, aber ich weiß grad leider nicht, was ich falsch mache.

    Zu Deiner Verteidigung: Dass man zwar reduzierte, aber komplette Beispiele zeigt, geht nicht aus SeppJs Link hervor, nur seinem Kommentar. Dein Job ist nicht das Zitieren von einigen Stellen, sondern das REDUZIEREN des Codes. Das heißt, Du kürzt da so viel wie geht, versuchst den Fehler zu isolieren, aber so, dass das immer noch ein vollständiges Programm ergibt. Fragmente allein bringen nichts.

    Das mit dem new[] da ist echt hässlich. Schade, dass Du keinen fähigen Prof hast, der Euch erstmal so wichtige Sachen wie <vector> erklärt. Oder heißt der Kurs "C/C++"? 🙄



  • Soll das heißen, dass ich mein gesamtes Programm gekürzt hier reinstellen soll?
    Ich dachte halt, dass das Ganze dadurch viel unübersichtlicher werden würde.

    Ich hoffe, ich hab euch richtig verstanden.

    Natuerlich.h :

    #include <iostream>
    #include <string>         // für Textinitialisierung
    
    using namespace std ;
    class Natuerlich
    {
    
    /***  private Daten  ***/
    
    	// Länge des Arrays
    	int  _nZiffer ;
    
    	// Array der Ziffernfolge
    	int* _ziffer ;
    
    /* ... */
    
    public:
    
    	// Umwandlungskonstruktor von long long
    	Natuerlich ( long long zahl ) ;
    
    /* ... */
    
    	friend ostream& operator << ( ostream& ostr, Natuerlich const& zahl ) ;
    
    } ;  // class Natuerlich
    

    Natuerlich.cpp :

    #include <cmath>          // für log10()
    #include <iostream>
    #include "Natuerlich.h"
    
    /* ... */
    
    Natuerlich::Natuerlich ( long long zahl )
    {
    	_nZiffer = int ( log10( double ( zahl ) ) ) + 1 ;
    	_ziffer = new int[ _nZiffer ] ;
    	int pot = 10 ;
    	for ( int i = 0 ; i < _nZiffer + 1 ; ++i )
    	{
    		_ziffer[ i ] = int ( ( zahl % pot ) / ( pot / 10 ) ) ;
    		zahl = zahl - ( zahl % pot ) ;
    		pot *= 10 ;
    	}
    
    }
    
    /* ... */
    
     ostream& operator << ( ostream& ostr, Natuerlich const& zahl )
    {
    	for ( int i = zahl.laenge() - 1 ;  i >= 0 ;  --i )
    	{
    		ostr << zahl._ziffer[ i ] ;
    	}
    	return ostr ;
    }
    

    main.cpp :

    long long test1 ;
    	cout << "obj1 (long long)	: " ;
    	cin >> test1 ;
    	cout << "obj1 (long long)	: " << test1 << endl ;
    	Natuerlich obj1 ( test1 ) ;
    	cout << "Nach Konstruktor	: " << obj1 << " ; " << obj1.laenge() << endl << endl ;
    

    Der Konstruktor muss den Fehler beinhalten, da die Ausgabe auf cout bei den anderen Objekten dieser Klasse problemlos funktioniert...

    Sorry für die Umstände und danke für eure Geduld. 🙂

    Ps: Ich bin mir sicher, sowas wie <Vector> wird noch kommen, aber für den Moment ist das mit dem new echt die beste Lösung, die ich kenne.


  • Mod

    _ziffer = new int[ _nZiffer ] ;
     // ...
     for ( int i = 0 ; i < _nZiffer + 1 ; ++i )
     {
      _ziffer[ i ] // ...
     }
    

    Welche Werte kann denn i wohl haben?



  • VollNoob schrieb:

    // Umwandlungskonstruktor von long long
    Natuerlich::Natuerlich ( long long zahl )
    {
    	_nZiffer = log10( double(zahl) ) + 1 ;
    	_ziffer = new int[ _nZiffer ] ;
    	int pot = 10 ;
    	for ( int i = 0 ; i < _nZiffer ; ++i )
    	{
    		_ziffer[ i ] = int ( ( zahl % pot ) / ( pot / 10 ) ) ;
    		zahl = zahl - ( zahl % pot ) ;
    		pot *= 10 ;
    	}
    
    }
    

    Abgesehen davon dass ich das für Quatsch halte (log10, viel zu komplizierte Art ins 10er System zu konvertieren etc.)...
    Also abgesehen davon denke ich der Fehler wird int pot = 10 ; sein. Weil int halt üblicherweise kleiner ist als long long .



  • Oh Mann... vielen, vielen Dank, hustbaer!!! Wie blöd von mir... Vielen Dank nochmals! 😃
    Es lag tatsächlich daran! :))


Anmelden zum Antworten