Probleme mit int_klasse



  • Hallo!
    ich bin dabei eine Klasse zu entwerfen, welche es ermoeglicht, positive Zahlen zu speichern, die groesser (2^32)-1 sind.
    Das Problem ist jedoch, dass mein Programm Fehler erzeugt sobald die Zahlen groesser (2^96)-1 werden.
    Ich scheine leider unfaehig zu sein den Fehler zu finden, ich hoffe hier kann mir geholfen werden..

    #include<iostream>
    #include<iomanip>
    #include<cmath>
    using namespace std;
    class long_unsigned
    	{
    	public:
    	long_unsigned();
    	long_unsigned(unsigned);
    	inline unsigned giveGR(){return GR;};
    	inline unsigned give(unsigned op){if(op<GR)return Z[op];else {add(1);return Z[GR-1];}};
    	void add(unsigned);
    	void set(int,unsigned);
    	void operator+=(long_unsigned);
    	void operator*=(int);
    	void kuerze();
    	void print();
    	private:
    	unsigned *Z;
    	unsigned GR;	
    	};
    long_unsigned::long_unsigned()
    	{
    	Z=new unsigned ;
    	GR=1;
    	Z[0]=0;	
    	}
    long_unsigned::long_unsigned(unsigned op)
    	{
    	Z=new unsigned;
    	GR=1;
    	Z[0]=op;	
    	}
    void long_unsigned::kuerze()
    	{
    	if(GR>1)
    		{
    		if(Z[GR-1]==0)
    			{
    			unsigned *new_Z=new unsigned [GR-1];
    			for(int i=0;i<GR-2;i++)
    				{
    				new_Z[i]=Z[i];
    				}
    			delete [] Z;
    			Z=new_Z;
    			GR--;
    			}
    		}
    	}
    
    void long_unsigned::print()
    	{
    	for(int i=0;i<GR;i++)
    	for(int j=0;j<32;j++)
    	{
    	if(j==0)cout<<"|";
    	if(Z[i]&(unsigned)pow(2.,j))cout<<"1";
    	else cout<<"0";
    	}
    	cout<<"|"<<endl;
    
    	}
    void long_unsigned::set(int nr, unsigned wert)
    	{
    	if(nr>=GR)add(nr-GR+1);
    	Z[nr]=wert;
    	}
    void long_unsigned::add(unsigned anz)
    	{
    	unsigned *new_Z=new unsigned [GR+anz];
    	for(int i=0;i<GR;i++)
    	new_Z[i]=Z[i];
    	delete [] Z;
    	Z=new_Z;
    	for(int i=GR;i<GR+anz;i++)
    	Z[i]=0;
    	GR=GR+anz;
    	}		
    void long_unsigned::operator+=(long_unsigned op)
    	{
    	bool merker=false;
    	int nr=0;
    	     do
    		{
    
    		unsigned act=0;
    		for(int i=0;i<32;i++)
    			{
    			if(merker)
    				{
    				if(Z[nr]&(unsigned)pow(2.,i)&&op.give(nr)&(unsigned)pow(2.,i))
    					{
    					act=act|(unsigned)pow(2.,i);
    					}
    				else
    					{
    					if(Z[nr]&(unsigned)pow(2.,i)||op.give(nr)&(unsigned)pow(2.,i))
    						{
    						merker=true;
    						}
    					else
    						{
    						act=act|(unsigned)pow(2.,i);
    						merker=false;
    						}
    					}
    				}
    			else
    				{
    				if(Z[nr]&(unsigned)pow(2.,i)&&op.give(nr)&(unsigned)pow(2.,i))
    					{
    					merker=true;
    					}
    				else
    					{
    					if(Z[nr]&(unsigned)pow(2.,i)||op.give(nr)&(unsigned)pow(2.,i))
    						{
    						act=act|(unsigned)pow(2.,i);
    						}
    					}
    				}
    			}
    		Z[nr]=act;
    
    		if(merker&&nr==GR-1){add(1);}
    		nr++;
    		}while(nr<GR);
    
    	}	
    void long_unsigned::operator*=(int op)
    	{
    	for(int i=1;i<op;i++)*this+=*this;
    
    	}		
    int main()
    {
    long_unsigned a(pow(2.,2));
    for(int i=0;i<150;i++)
    {
    a+=a;
    
    a.print();
    }
    return 0;
    }
    

    mfg Zarathustra23



  • Ist ja interessant.

    Zarathustra23 schrieb:

    ...mein Programm Fehler erzeugt sobald die Zahlen groesser (2^96)-1 werden....

    Welche denn ? 😉 😉

    Sorry, ein wenig mehr Information wäre hilfreich. Ansonsten kann ich nur zu einem Debugger raten (ist sowieso eine gute Idee).

    Gruß,

    Simon2.



  • |00010000000000000000000000000000|
    |00001000000000000000000000000000|
    |00000100000000000000000000000000|
    |00000010000000000000000000000000|
    |00000001000000000000000000000000|
    |00000000100000000000000000000000|
    |00000000010000000000000000000000|
    |00000000001000000000000000000000|
    |00000000000100000000000000000000|
    |00000000000010000000000000000000|
    |00000000000001000000000000000000|
    |00000000000000100000000000000000|
    |00000000000000010000000000000000|
    |00000000000000001000000000000000|
    |00000000000000000100000000000000|
    |00000000000000000010000000000000|
    |00000000000000000001000000000000|
    |00000000000000000000100000000000|
    |00000000000000000000010000000000|
    |00000000000000000000001000000000|
    |00000000000000000000000100000000|
    |00000000000000000000000010000000|
    |00000000000000000000000001000000|
    |00000000000000000000000000100000|
    |00000000000000000000000000010000|
    |00000000000000000000000000001000|
    |00000000000000000000000000000100|
    |00000000000000000000000000000010|
    |00000000000000000000000000000001|
    |00000000000000000000000000000000|10000000000000000000000000000000|
    |00000000000000000000000000000000|01000000000000000000000000000000|
    |00000000000000000000000000000000|00100000000000000000000000000000|
    |00000000000000000000000000000000|00010000000000000000000000000000|
    |00000000000000000000000000000000|00001000000000000000000000000000|
    |00000000000000000000000000000000|00000100000000000000000000000000|
    |00000000000000000000000000000000|00000010000000000000000000000000|
    |00000000000000000000000000000000|00000001000000000000000000000000|
    |00000000000000000000000000000000|00000000100000000000000000000000|
    |00000000000000000000000000000000|00000000010000000000000000000000|
    |00000000000000000000000000000000|00000000001000000000000000000000|
    |00000000000000000000000000000000|00000000000100000000000000000000|
    |00000000000000000000000000000000|00000000000010000000000000000000|
    |00000000000000000000000000000000|00000000000001000000000000000000|
    |00000000000000000000000000000000|00000000000000100000000000000000|
    |00000000000000000000000000000000|00000000000000010000000000000000|
    |00000000000000000000000000000000|00000000000000001000000000000000|
    |00000000000000000000000000000000|00000000000000000100000000000000|
    |00000000000000000000000000000000|00000000000000000010000000000000|
    |00000000000000000000000000000000|00000000000000000001000000000000|
    |00000000000000000000000000000000|00000000000000000000100000000000|
    |00000000000000000000000000000000|00000000000000000000010000000000|
    |00000000000000000000000000000000|00000000000000000000001000000000|
    |00000000000000000000000000000000|00000000000000000000000100000000|
    |00000000000000000000000000000000|00000000000000000000000010000000|
    |00000000000000000000000000000000|00000000000000000000000001000000|
    |00000000000000000000000000000000|00000000000000000000000000100000|
    |00000000000000000000000000000000|00000000000000000000000000010000|
    |00000000000000000000000000000000|00000000000000000000000000001000|
    |00000000000000000000000000000000|00000000000000000000000000000100|
    |00000000000000000000000000000000|00000000000000000000000000000010|
    |00000000000000000000000000000000|00000000000000000000000000000001|
    |00000000000000000000000000000000|00000000000000000000000000000000|10000000000000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|01000000000000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00100000000000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00010000000000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00001000000000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000100000000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000010000000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000001000000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000100000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000010000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000001000000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000100000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000010000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000001000000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000100000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000010000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000001000000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000100000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000010000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000001000000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000100000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000010000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000001000000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000000100000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000000010000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000000001000000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000000000100000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000000000010000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000000000001000|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000000000000100|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000000000000010|
    |00000000000000000000000000000000|00000000000000000000000000000000|00000000000000000000000000000001|
    *** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0804b008 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb7ce6a85]
    /lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7cea4f0]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7eb1b11]
    /usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb7eb1b6d]
    ./a.out(__gxx_personality_v0+0x382)[0x8048af6]
    ./a.out[0x8049235]
    ./a.out[0x8048ca9]
    ./a.out[0x80490f8]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7c91450]
    ./a.out(__gxx_personality_v0+0x3d)[0x80487b1]
    ======= Memory map: ========
    08048000-0804a000 r-xp 00000000 08:12 8831496    /mnt/no2/tino/QUELLTEXTE/AAA_neues/a.out
    0804a000-0804b000 rw-p 00001000 08:12 8831496    /mnt/no2/tino/QUELLTEXTE/AAA_neues/a.out
    0804b000-0806c000 rw-p 0804b000 00:00 0          [heap]
    b7b00000-b7b21000 rw-p b7b00000 00:00 0 
    b7b21000-b7c00000 ---p b7b21000 00:00 0 
    b7c7a000-b7c7b000 rw-p b7c7a000 00:00 0 
    b7c7b000-b7dc4000 r-xp 00000000 08:01 689466     /lib/tls/i686/cmov/libc-2.7.so
    b7dc4000-b7dc5000 r--p 00149000 08:01 689466     /lib/tls/i686/cmov/libc-2.7.so
    b7dc5000-b7dc7000 rw-p 0014a000 08:01 689466     /lib/tls/i686/cmov/libc-2.7.so
    b7dc7000-b7dca000 rw-p b7dc7000 00:00 0 
    b7dca000-b7dd4000 r-xp 00000000 08:01 671809     /lib/libgcc_s.so.1
    b7dd4000-b7dd5000 rw-p 0000a000 08:01 671809     /lib/libgcc_s.so.1
    b7dd5000-b7df8000 r-xp 00000000 08:01 689474     /lib/tls/i686/cmov/libm-2.7.so
    b7df8000-b7dfa000 rw-p 00023000 08:01 689474     /lib/tls/i686/cmov/libm-2.7.so
    b7dfa000-b7ee2000 r-xp 00000000 08:01 18925      /usr/lib/libstdc++.so.6.0.9
    b7ee2000-b7ee5000 r--p 000e8000 08:01 18925      /usr/lib/libstdc++.so.6.0.9
    b7ee5000-b7ee7000 rw-p 000eb000 08:01 18925      /usr/lib/libstdc++.so.6.0.9
    b7ee7000-b7eee000 rw-p b7ee7000 00:00 0 
    b7efd000-b7eff000 rw-p b7efd000 00:00 0 
    b7eff000-b7f00000 r-xp b7eff000 00:00 0          [vdso]
    b7f00000-b7f1a000 r-xp 00000000 08:01 671763     /lib/ld-2.7.so
    b7f1a000-b7f1c000 rw-p 00019000 08:01 671763     /lib/ld-2.7.so
    bfdd7000-bfdec000 rw-p bffeb000 00:00 0          [stack]
    Aborted
    

    Das Programm faengt bei 2^4 oder so an, und verdoppelt dann immer... wenn 32bit voll sind und bei der Addition noch ein uebertrag bleibt, werden einfach neue 4 byte angefordert.
    Ab 2^96 kommt er dann nich mehr auf seinen Arbeitsspeicher fit, wie die ausgabe erahnen laesst...

    mfg



  • Es liegt bestimmt nicht daran, aber eine Kleinigkeit: Du forderst im Konstruktor mit "new unsigned" Speicher an, gibst ihn aber mit "delete**[]**" frei, also am Besten überall mit "new[]" anfordern.

    edit: Kann's sein, dass du in der Methode "operator+=" gar nicht den Speicher vergrößerst, wenn's erforderlich ist?



  • Erster Punkt bachte mich nicht weiter, haette mich auch gewundert wenn der g++ daran gescheitert waere^^

    zweitne Punkt kann ich leider nur dementieren

    Zeile 127:

    if(merker&&nr==GR-1){add(1);}
    

    (Wenn Uebertrag und kein Platz mehr, neuen Speicher anfordern)

    mfg



  • Zarathustra23 schrieb:

    Erster Punkt bachte mich nicht weiter, haette mich auch gewundert wenn der g++ daran gescheitert waere^^

    Wenn die Klasse portabel sein soll (also auch auf anderen Plattformen/Compilern laufen soll), würde ich schon sauber programmieren.

    Zarathustra23 schrieb:

    zweitne Punkt kann ich leider nur dementieren

    Oh stimmt, das "add" haste aber auch gut versteckt 😉


  • Mod

    Deine Klasse besitzt einen Zeiger auf allokierten Speicher, aber keinen selbstgeschriebenen Copy-ctor oder Zuweisungsoperator. Der Copyctor wird zumindest für das Funktionsargument von += benötigt. Zwar sollte dies wohl ohnehin besser eine Referenz auf const sein - trotzdem ist die normale Kopierinfrastruktur wichtig. Generell würde ich empfehlen, diese bei jeder neuen Klasse als erstes zu implementieren - dann kann man das nicht vergessen. Es gibt noch eine ganze Reihe anderer Fehler, aber die sind nicht ursächlich für den Absturz.
    Nebenbei: das bitweise addieren ist reichlich umständlich. Du solltest dir zunutze machen, dass vorzeichenlose Arithmetik nicht überlaufen kann.

    c = a + b + carry;
    carry = carry ? c <= a : c < a;
    


  • Vielleicht kannst Du Dir hier etwas abschauen:
    http://mattmccutchen.net/bigint/


Anmelden zum Antworten