Infinite Precision Arithmetic Class [Incomplete]

Posts 1–8 of 8 · Page 1 of 1
Infinite Precision Arithmetic Class [Incomplete]
I'll update this as I go, but for now I just want to show off my awesome math skills with this infinite-precision arithmetic class I made.
It can only preform addition and subtraction, but soon I'll add multiplication, division and modulo operations. I invite you to test this class and see if the calculations are working as they should. I think I got them right but you never know so please report any bugs you might find.

With this class you can use numbers who's size is only limited by the amount of memory on your system and the speed of your processor. Why would anyone need such large numbers? I have no idea about others but I know that I need them to hold ridiculously large prime numbers for my implementation of the RSA algorithm which I'm going to post here later

There are a few inconsistencies in how strict I am checking for size differences, this is because I started working on this project while I was awake, now several hours later I feel like sleeping for a day or two .

ExtendedArithmetic.h
Code:
#ifndef EXT_AR_H
#define EXT_AR_H

/*
infinite-precision arithmetic class
by SCHiM
*/

class ArbitraryArithmetic{

long MyLength;
unsigned char* Number; 

public:
//constructor
ArbitraryArithmetic(long Lenght );

//debug/verification
void print();

//information
long getsize() const;
unsigned char* getnumber() const;

//operators
void operator = (unsigned __int64 n);
void operator = (const ArbitraryArithmetic &);

void operator -= (unsigned __int64 n);
void operator += (unsigned __int64 n);

};

#endif
ExtendedArithmetic.cpp
Code:
#include "ExtendedArithmetic.h"
#include <iostream>

ArbitraryArithmetic::ArbitraryArithmetic(long Length){
	MyLength = Length;
	Number = new unsigned char[ Length ];
	for(int i = 0; i <= MyLength; i++){
		Number[i] = 0; 	
	}
return;
}

void ArbitraryArithmetic::print(){

	for( int i = MyLength; i >= 0 ; i--)
			printf("%.2x", Number[i]);

	printf("\n");
}

long ArbitraryArithmetic::getsize() const{
	return MyLength;
}

unsigned char* ArbitraryArithmetic::getnumber() const{
	return Number;
}


void ArbitraryArithmetic::operator =(unsigned __int64 n){

	memcpy( (void*)Number, (void*)&n, sizeof( unsigned __int64) );

	for(int i = sizeof( unsigned __int64); i <= MyLength; i++)
		Number[i] = 0;
	

}

void ArbitraryArithmetic::operator =(const ArbitraryArithmetic &n){

		//if I am myself :p
	if(&n == this) return;

int i = 0;

long nLength = n.getsize();
unsigned char* ptr = n.getnumber();

long Lesser = nLength < MyLength ? nLength : MyLength;

	for( i = 0 ; i <= Lesser; i++)
			Number[i] = ptr[i];

	if( Lesser == MyLength )
		return;
		
	for( ; i <= MyLength; i++)
		Number[i] = 0;
return;
}

void ArbitraryArithmetic::operator -=(unsigned __int64 n){

unsigned char* nPtr = (unsigned char*) &n;

int Lesser = sizeof( unsigned __int64 ) < MyLength ?  sizeof( unsigned __int64 ) : MyLength;

	for( int i = 0; i < Lesser; i++){
		if( Number[i] < nPtr[i] ){
			    for(int y = 1; y+i < Lesser; y++){
					if( Number[i+y] != 0 ){
						Number[i+y]--;
						 break;
					} else {
						Number[i+y] = 0xFF;
					}
				}
				Number[i] = ( 0x100 - (nPtr[i] - Number[i]) );
				nPtr[i] = 0;
		}
			
		Number[i] -= nPtr[i];

	}

}

void ArbitraryArithmetic::operator +=(unsigned __int64 n){

unsigned short r = 0;
unsigned char* nPtr = (unsigned char*) &n;
unsigned char* rPtr = (unsigned char*) &r;
int Lesser = sizeof( unsigned __int64 ) < MyLength ?  sizeof( unsigned __int64 ) : MyLength;

	for(int i = 0; i < Lesser; i++){
		 r = Number[i] + nPtr[i];
			if( r > 0xff ){
				Number[i] = rPtr[0];
					for(int y = 1; y+i < MyLength; i++){
						if( rPtr[1] != 0){
							if( y+i < Lesser )
							r = Number[i+y] + nPtr[i+y] + rPtr[1]; 
							else 
							r = Number[i+y] + rPtr[1];

							Number[i+y] = rPtr[0];
						} else {
							break;
						}
					}
			} else {
				Number[i] += nPtr[i];
			}
	}
}
Usage/main.cpp

Code:
int main(){

uint64 Prime1, Prime2, N;
/*
	 GeneratePrimes( &Prime1, &Prime2);
	N = Prime1 * Prime2;
	printf("Found N [%lld]\n", N);
*/
ArbitraryArithmetic LargeNumber( 32 );
ArbitraryArithmetic SmallerNumber( 32 );


uint64 A = 0x100;
uint64 b = 0xFffffAc33Defff;

LargeNumber = A;
SmallerNumber = LargeNumber;

LargeNumber -= 0x1;

//printf("Small number is: ");
SmallerNumber.print();

//printf("Large number is: ");
LargeNumber.print();

	//printf(" %d ", phi( 32231  ) );
	system("pause");
	return 0;
}
Ok, in this update I bring to you: multiplication, off-by-1 bug fix in the constructor, an improved constructor, improved copy operator, comparison operators, overloaded assignment operators and a better enforcement of size.

Division and modulo operations are still in the workings. Comparison between two instances of the same class are also on their way.

ExtendedArithmetic.cpp
Code:
#include "ExtendedArithmetic.h"
#include <iostream>

ArbitraryArithmetic::ArbitraryArithmetic(long Length, unsigned __int64 n){

	MyLength = Length;
	Number = new unsigned char[ Length ];
	int i = 0; 

	if( n ){

		unsigned char* nPtr = (unsigned char*) &n;
		int Lesser = sizeof( unsigned __int64 ) < MyLength ?  sizeof( unsigned __int64 ) : MyLength;

		for( i = 0; i < Lesser; i++){
			Number[i] = nPtr[i];
		}

		if( Lesser == MyLength)
				return;

	}
	for(; i < MyLength; i++){
		Number[i] = 0; 	
	}
return;
}

void ArbitraryArithmetic::print(){

	for( int i = MyLength-1; i >= 0 ; i--)
			printf("%.2x", Number[i]);

	printf("\n");
}

long ArbitraryArithmetic::getsize() const{
	return MyLength;
}

unsigned char* ArbitraryArithmetic::getnumber() const{
	return Number;
}


void ArbitraryArithmetic::operator =(unsigned __int64 n){

	if( MyLength < sizeof( unsigned __int64) ){
		delete [] Number;
		Number = new unsigned char[ sizeof( unsigned __int64) ];
	}
	memcpy( (void*)Number, (void*)&n, sizeof( unsigned __int64) );

	for(int i = sizeof( unsigned __int64); i <= MyLength; i++)
		Number[i] = 0;
}

void ArbitraryArithmetic::operator =(const ArbitraryArithmetic &n){
		//if I am myself :p
	if(&n == this) 
		return;

	int Lesser = n.getsize() < MyLength ?  n.getsize() : MyLength;

	if( Lesser == MyLength && MyLength != n.getsize() ){
		MyLength = n.getsize();

			if( Number )
				delete [] Number;

			Number = new unsigned char[ MyLength ];
			memcpy( (void*)Number, (void*)n.getnumber(), MyLength );
	} else {
		unsigned char* nPtr = n.getnumber();
		int i = 0;

		for( i = 0; i <= Lesser; i++)
			Number[i] = nPtr[i];

		for( i; i <= MyLength; i++)
			Number[i] = 0;
	
	}

return;
}

void ArbitraryArithmetic::shift( int numdigits ){

if( !numdigits ) return;

Number[ MyLength ] = 0;
	do{
			for(int i = MyLength-1; i >= 1; i--){
				Number[i] = Number[i-1];
			}
		Number[0] = 0;
	} while( --numdigits );
return;
}

int ArbitraryArithmetic::Compare(unsigned __int64 n) const{
  int i;
  for (i = MyLength-1; i >= 1; i--){
    if (Number[i] != 0)
      return 1;
  }
  return Number[0] > n ? 1 : Number[0] < n ? -1 : 0;
}


void ArbitraryArithmetic::operator -=(unsigned __int64 n){

unsigned char* nPtr = (unsigned char*) &n;
int Lesser = sizeof( unsigned __int64 ) < MyLength ?  sizeof( unsigned __int64 ) : MyLength;

	for( int i = 0; i < Lesser; i++){
		if( Number[i] < nPtr[i] ){
			    for(int y = 1; y+i < Lesser; y++){
					if( Number[i+y] != 0 ){
						Number[i+y]--;
						 break;
					} else {
						Number[i+y] = 0xFF;
					}
				}
				Number[i] = ( 0x100 - (nPtr[i] - Number[i]) );
		} else {
			Number[i] -= nPtr[i];
		}

	}

}

void ArbitraryArithmetic::operator -=(const ArbitraryArithmetic &n){

unsigned char* nPtr = (unsigned char*) n.getnumber();
int Lesser = n.getsize() < MyLength ?  n.getsize() : MyLength;

	for( int i = 0; i < Lesser; i++){
		if( Number[i] < nPtr[i] ){
			    for(int y = 1; y+i < MyLength; y++){
					if( Number[i+y] != 0 ){
						Number[i+y]--;
						 break;
					} else {
						Number[i+y] = 0xFF;
					}
				}
				Number[i] = ( 0x100 - (nPtr[i] - Number[i]) );
		} else {
			Number[i] -= nPtr[i];
		}

	}

}

void ArbitraryArithmetic::operator +=(unsigned __int64 n){

unsigned short r = 0;
unsigned char* nPtr = (unsigned char*) &n;
unsigned char* rPtr = (unsigned char*) &r;
int Lesser = sizeof( unsigned __int64 ) < MyLength ?  sizeof( unsigned __int64 ) : MyLength;

	for(int i = 0; i < Lesser; i++){
		 r = Number[i] + nPtr[i];
			if( r > 0xff ){
				Number[i] = rPtr[0];
					for(int y = 1; y+i < MyLength; i++){
						if( rPtr[1] != 0){
							if( y+i < Lesser )
							r = Number[i+y] + nPtr[i+y] + rPtr[1]; 
							else 
							r = Number[i+y] + rPtr[1];

							Number[i+y] = rPtr[0];
						} else {
							break;
						}
					}
			} else {
				Number[i] += nPtr[i];
			}
	}
}

void ArbitraryArithmetic::operator +=(const ArbitraryArithmetic &n){

unsigned short r = 0;
unsigned char* nPtr = (unsigned char*) n.getnumber();
unsigned char* rPtr = (unsigned char*) &r;
int Lesser = n.getsize() < MyLength ?  n.getsize() : MyLength;

	for(int i = 0; i < Lesser; i++){
		 r = Number[i] + nPtr[i];
			if( r > 0xff ){
				Number[i] = rPtr[0];
					for(int y = 1; y+i < MyLength; i++){
						if( rPtr[1] != 0){
							if( y+i < Lesser )
							r = Number[i+y] + nPtr[i+y] + rPtr[1]; 
							else 
							r = Number[i+y] + rPtr[1];

							Number[i+y] = rPtr[0];
						} else {
							break;
						}
					}
			} else {
				Number[i] += nPtr[i];
			}
	}

}


void ArbitraryArithmetic::operator *=( __int64 n){

	if( n > 1 ){
		unsigned char* nPtr = (unsigned char*) &n;
		ArbitraryArithmetic r( 32, 0 );
		ArbitraryArithmetic rr( 32, 0 );
		ArbitraryArithmetic rrr( 32, 0 );
		rrr = 0;
			for(int i = 0; i < MyLength; i++){
				rr = 0;
					for(int y = 0; y < sizeof( unsigned __int64 ); y++){
					 r = 0;
						r += Number[i] * nPtr[y];
							if( y >= 1 )
									r.shift( y );
						rr += r;
					}
					if( i >= 1 )
						rr.shift( i );
				rrr += rr;
			}
			*this = rrr;
	} else if( n == 1 ) {
		return;
	} else {
		for(int i = 0; i != MyLength; i++)
			Number[i] = 0;
		return;
	}
return;
}

void ArbitraryArithmetic::operator *=(const ArbitraryArithmetic &n){

		if( n > 1 ){
		unsigned char* nPtr = (unsigned char*) n.getnumber();
		ArbitraryArithmetic r( 32, 0 );
		ArbitraryArithmetic rr( 32, 0 );
		ArbitraryArithmetic rrr( 32, 0 );
		rrr = 0;
			for(int i = 0; i < MyLength; i++){
				rr = 0;
					for(int y = 0; y < n.getsize(); y++){
					 r = 0;
						r += Number[i] * nPtr[y];
							if( y >= 1 )
									r.shift( y );
						rr += r;
					}
					if( i >= 1 )
						rr.shift( i );
				rrr += rr;
			}
			*this = rrr;
	} else if( n == 1 ) {
		return;
	} else {
		for(int i = 0; i != MyLength; i++)
			Number[i] = 0;
		return;
	}
return;
}
ExtendedArithmetic.h
Code:
#ifndef EXT_AR_H
#define EXT_AR_H

/*
infinite-precision arithmetic class
by SCHiM
*/

class ArbitraryArithmetic{

long MyLength;
unsigned char* Number; 

public:
//constructor
ArbitraryArithmetic(long Lenght, unsigned __int64 n);

//debug/verification
void print();

//information
long getsize() const;
unsigned char* getnumber() const;

//support operators
void shift( int numdigits );
int Compare(unsigned __int64 n) const;

//assignment operators
void operator = (unsigned __int64 n);
void operator = (const ArbitraryArithmetic &);

void operator -= (unsigned __int64 n);
void operator -= (const ArbitraryArithmetic &);

void operator += (unsigned __int64 n);
void operator += (const ArbitraryArithmetic &);

void operator *= ( __int64 n);
void operator *= (const ArbitraryArithmetic &);

//comparason operators
bool ArbitraryArithmetic::operator == (unsigned __int64 n) const {return Compare(n) == 0;}
bool ArbitraryArithmetic::operator != (unsigned __int64 n) const {return Compare(n) != 0;}
bool ArbitraryArithmetic::operator >  (unsigned __int64 n) const {return Compare(n) >  0;}
bool ArbitraryArithmetic::operator >= (unsigned __int64 n) const {return Compare(n) >= 0;}
bool ArbitraryArithmetic::operator <  (unsigned __int64 n) const {return Compare(n) <  0;}
bool ArbitraryArithmetic::operator <= (unsigned __int64 n) const {return Compare(n) <= 0;}

};

#endif
looks good.
lol...... random, but nice.
Thanks for the positive posts! Anyway here's the last update on this class. In this update I fix even more off-by-1 errors (in the byte shifting code), I added division and modulus operators and fixed a bug in the comparison code where the comparison would stop if one of the two numbers had more digits.

I've also added a destructor and 2 new support operators for bit- and bytewise shifting and a function to extract the remainder of a previous devision.

The division code is not the of the same quality as the other operators, since devision was too complex to do bytewise (sheer recursiveness) I used repeated subtraction to find the answer. Once you start dividing any number by another number with more then 16 digits you're in trouble. When the divisor is smaller then 16 digits the division is fast enough. If you want to optimize I suggest changing the multiplication operator and the copy constructor in such a way that they don't grow your number when multiplying with another instance of this class (it currently does this to accommodate to the possible increase in digits due to the multiplication)

For instance if you were to multiply 00001 and 00001 you'd get: 000000001.

ExtendedArithmetic.cpp
Code:
#include "ExtendedArithmetic.h"
#include <iostream>

ArbitraryArithmetic::ArbitraryArithmetic(long Length, unsigned __int64 n){
	MyLength = Length;
	Number = new unsigned char[ Length ];
	int i = 0; 

	if( n ){

		unsigned char* nPtr = (unsigned char*) &n;
		int Lesser = sizeof( unsigned __int64 ) < MyLength ?  sizeof( unsigned __int64 ) : MyLength;

		for( i = 0; i < Lesser; i++){
			Number[i] = nPtr[i];
		}

		if( Lesser == MyLength)
				return;

	}
	for(; i < MyLength; i++){
		Number[i] = 0; 	
	}
return;
}

ArbitraryArithmetic::ArbitraryArithmetic( ArbitraryArithmetic &n ){

	MyLength = n.getsize();
	Number = new unsigned char[ MyLength ];

	memcpy( (void*) Number, (void*) n.getnumber(), MyLength );

return;
}

ArbitraryArithmetic::~ArbitraryArithmetic(){
	delete [] Number;
}

void ArbitraryArithmetic::print(){

	for( int i = MyLength-1; i >= 0 ; i--)
			printf("%.2x", Number[i]);

	printf("\n");
}

long ArbitraryArithmetic::getsize() const{
	return MyLength;
}

unsigned __int64 ArbitraryArithmetic::getremainder() const{
	return Remainder;
}

unsigned __int64* ArbitraryArithmetic::touint64(){
	return (unsigned __int64*)Number;
}


unsigned char* ArbitraryArithmetic::getnumber() const{
	return Number;
}


void ArbitraryArithmetic::operator =(unsigned __int64 n){

	if( MyLength < sizeof( unsigned __int64) ){
		delete [] Number;
		Number = new unsigned char[ sizeof( unsigned __int64) ];
	}
	memcpy( (void*)Number, (void*)&n, sizeof( unsigned __int64) );

	for(int i = sizeof( unsigned __int64); i < MyLength; i++)
		Number[i] = 0;
}

void ArbitraryArithmetic::operator =(const ArbitraryArithmetic &n){
		//if I am myself :p
	if(&n == this) 
		return;

	int Lesser = n.getsize() < MyLength ?  n.getsize() : MyLength;

	if( Lesser == MyLength && MyLength != n.getsize() ){
		MyLength = n.getsize();

			if( Number )
				delete [] Number;

			Number = new unsigned char[ MyLength ];
			memcpy( (void*)Number, (void*)n.getnumber(), MyLength );
	} else {
		unsigned char* nPtr = n.getnumber();
		int i = 0;

		for( i = 0; i < Lesser; i++)
			Number[i] = nPtr[i];

		for( i; i < MyLength; i++)
			Number[i] = 0;
	
	}

return;
}

void ArbitraryArithmetic::shift( int numdigits ){

if( !numdigits ) return;

Number[ MyLength-1 ] = 0;
	do{
			for(int i = MyLength-2; i >= 1; i--){
				Number[i] = Number[i-1];
			}
		Number[0] = 0;
	} while( --numdigits );
return;
}

void ArbitraryArithmetic::bitshift( int bits ){
if( !bits ) return;
	bool bitset;
	do{
		unsigned char* tmp = new unsigned char[ MyLength ];
		memset((void*)tmp, 0, MyLength);

		for(int i = (MyLength*8)-1; i > 0; i--){
			bitset = Number[i/8] & (1 << i-((i/8)*8) );
			if( bitset ){
					i++;
					tmp[i/8] |= 1 << (i-((i/8)*8)); 
					i--;
			}

		}
		delete [] Number;
		Number = tmp;
	} while ( --bits );
}


void ArbitraryArithmetic::trim( int numdigits ){

		if( numdigits <= 0 || MyLength <= numdigits  ) 
				return;

		MyLength -= numdigits;

		unsigned char* temp = new unsigned char[ MyLength ];

		memcpy( (void*)temp, (void*)Number,  MyLength  );

		delete [] Number;

		Number = temp;

return;
}

void ArbitraryArithmetic::chop( int numdigits ){
	
		if( numdigits <= 0 || MyLength <= numdigits ) 
				return;

		MyLength -= numdigits;

		unsigned char* temp = new unsigned char[  MyLength  ];

		memcpy( (void*)temp, (void*)&Number[numdigits],  MyLength );

		delete [] Number;

		Number = temp;

return;	
}

unsigned __int64 ArbitraryArithmetic::getremainder(){
	return Remainder;
}


int ArbitraryArithmetic::Compare(unsigned __int64 n) const{
  int i;
  for (i = MyLength-1; i >= 1; i--){
    if (Number[i] != 0)
      return 1;
  }
  return Number[0] > n ? 1 : Number[0] < n ? -1 : 0;
}

int ArbitraryArithmetic::Compare(const ArbitraryArithmetic &n) const{

  int i;
  unsigned char* nPtr = n.getnumber();
  int Lesser = n.getsize() < MyLength ?  n.getsize() : MyLength;


  if (MyLength > n.getsize()){
    for (i = MyLength-1; i >= n.getsize(); i--){
		if (Number[i] != 0){
        return 1;
		}
    }
  } 
  
  if (n.getsize() > MyLength){
    for (i = n.getsize()-1; i >= MyLength; i--){
		if (nPtr[i] != 0){
        return -1;
		}
    }
  }

    i = Lesser-1;

	  while (true){
		  if (Number[i] > nPtr[i]){
		  return 1;
		  }
		if (Number[i] < nPtr[i]){
		  return -1;
		}
		if (i < 0){
		  return 0;
		}
		i--;
	  }

return 0;
}

void ArbitraryArithmetic::operator -=(unsigned __int64 n){

unsigned char* nPtr = (unsigned char*) &n;
int Lesser = sizeof( unsigned __int64 ) < MyLength ?  sizeof( unsigned __int64 ) : MyLength;

	for( int i = 0; i < Lesser; i++){
		if( Number[i] < nPtr[i] ){
			    for(int y = 1; y+i < Lesser; y++){
					if( Number[i+y] != 0 ){
						Number[i+y]--;
						 break;
					} else {
						Number[i+y] = 0xFF;
					}
				}
				Number[i] = ( 0x100 - (nPtr[i] - Number[i]) );
		} else {
			Number[i] -= nPtr[i];
		}

	}

}

void ArbitraryArithmetic::operator -=(const ArbitraryArithmetic &n){

unsigned char* nPtr = (unsigned char*) n.getnumber();
int Lesser = n.getsize() < MyLength ?  n.getsize() : MyLength;

	for( int i = 0; i < Lesser; i++){
		if( Number[i] < nPtr[i] ){
			    for(int y = 1; y+i < MyLength; y++){
					if( Number[i+y] != 0 ){
						Number[i+y]--;
						 break;
					} else {
						Number[i+y] = 0xFF;
					}
				}
				Number[i] = ( 0x100 - (nPtr[i] - Number[i]) );
		} else {
			Number[i] -= nPtr[i];
		}

	}

}

void ArbitraryArithmetic::operator +=(unsigned __int64 n){

unsigned short r = 0;
unsigned char* nPtr = (unsigned char*) &n;
unsigned char* rPtr = (unsigned char*) &r;
int Lesser = sizeof( unsigned __int64 ) < MyLength ?  sizeof( unsigned __int64 ) : MyLength;

	for(int i = 0; i < Lesser; i++){
		 r = Number[i] + nPtr[i];
			if( r > 0xff ){
				Number[i] = rPtr[0];
					for(int y = 1; y+i < MyLength; i++){
						if( rPtr[1] != 0){
							if( y+i < Lesser )
							r = Number[i+y] + nPtr[i+y] + rPtr[1]; 
							else 
							r = Number[i+y] + rPtr[1];

							Number[i+y] = rPtr[0];
						} else {
							break;
						}
					}
			} else {
				Number[i] += nPtr[i];
			}
	}
}

void ArbitraryArithmetic::operator +=(const ArbitraryArithmetic &n){

unsigned short r = 0;
unsigned char* nPtr = (unsigned char*) n.getnumber();
unsigned char* rPtr = (unsigned char*) &r;
int Lesser = n.getsize() < MyLength ?  n.getsize() : MyLength;

	for(int i = 0; i < Lesser; i++){
		 r = Number[i] + nPtr[i];
			if( r > 0xff ){
				Number[i] = rPtr[0];
					for(int y = 1; y+i < MyLength; i++){
						if( rPtr[1] != 0){
							if( y+i < Lesser )
							r = Number[i+y] + nPtr[i+y] + rPtr[1]; 
							else 
							r = Number[i+y] + rPtr[1];

							Number[i+y] = rPtr[0];
						} else {
							break;
						}
					}
			} else {
				Number[i] += nPtr[i];
			}
	}

}


void ArbitraryArithmetic::operator *=( __int64 n){

	if( n > 1 ){
		unsigned char* nPtr = (unsigned char*) &n;
		ArbitraryArithmetic r( 32, 0 );
		ArbitraryArithmetic rr( 32, 0 );
		ArbitraryArithmetic rrr( 32, 0 );
		rrr = 0;
			for(int i = 0; i < MyLength; i++){
				rr = 0;
					for(int y = 0; y < sizeof( unsigned __int64 ); y++){
					 r = 0;
						r += Number[i] * nPtr[y];
							if( y >= 1 )
									r.shift( y );
						rr += r;
					}
					if( i >= 1 )
						rr.shift( i );
				rrr += rr;
			}
			*this = rrr;
	} else if( n == 1 ) {
		return;
	} else {
		for(int i = 0; i != MyLength; i++)
			Number[i] = 0;
		return;
	}
return;
}

void ArbitraryArithmetic::operator *=(const ArbitraryArithmetic &n){

int Lesser = n.getsize() < MyLength ?  n.getsize() : MyLength;
int Greater = Lesser < MyLength ? MyLength : Lesser;

ArbitraryArithmetic r( Greater*2, 0 );
ArbitraryArithmetic rr( Greater*2, 0 );
ArbitraryArithmetic rrr( Greater*2, 0 );

	if( n > 1 ){
		unsigned char* nPtr = (unsigned char*) n.getnumber();
		rrr = 0;
			for(int i = 0; i < MyLength; i++){
				rr = 0;
					for(int y = 0; y < n.getsize(); y++){
					 r = 0;
						r += Number[i] * nPtr[y];
							if( y >= 1 )
									r.shift( y );
						rr += r;
					}
					if( i >= 1 )
						rr.shift( i );
				rrr += rr;
			}
			*this = rrr;
	} else if( n == 1 ) {
		return;
	} else {
		for(int i = 0; i < MyLength; i++)
			Number[i] = 0;
		return;
	}
return;
}

void ArbitraryArithmetic::operator /=(__int64 n){

	ArbitraryArithmetic r( 32, n );

	if( r < 1 ){
		Remainder = 0;
		*this = 0;
	}

	if( r == *this ){
		Remainder = 0;
		*this = 1;
		return;
	}	
	if( r > *this ){
		Remainder = n;
		*this = 0;
		return;
	}

	unsigned __int64 qotient = 1;

	while( true ){
		qotient++;
		r = qotient*n;
		if( r == *this ){
			Remainder = 0;
			*this = qotient;
			return;
		}
		if( r > *this ){
			qotient--;
		    r = qotient*n;
			Remainder = ( *this->touint64() - *r.touint64() );
			*this = qotient;
			return;
		}

	}
return;
}

void ArbitraryArithmetic::operator /=(const ArbitraryArithmetic &n){

	if( n < 1 ){
		Remainder = 0;
		*this = 0;
		return;
	}

	if( n == *this ){
		Remainder = 0;
		*this = 1;
		return;
	}	
	if( n > *this ){
		*this = n;
		Remainder = *this->touint64();
		*this = 0;
		return;
	}

	ArbitraryArithmetic qotient( n.getsize(), 1);
	ArbitraryArithmetic r( n.getsize()*2, 0);

	while( true ){
		qotient += 1;

		r = qotient;
		r *= n;
		r.trim( r.getsize() - this->getsize() );

		if( r == *this ){
			Remainder = 0;
			*this = qotient;
			return;
		}
		if( r > *this ){
			qotient -= 1;
			r = qotient;
			r *= n;
			r.trim( r.getsize() - this->getsize() );

			Remainder = ( *this->touint64() - *r.touint64() );
			*this = qotient;
			return;
		}

	}
return;
}

void ArbitraryArithmetic::operator %=(__int64 n){
	
	ArbitraryArithmetic r( *this );

	r /= n;
	*this = r.getremainder();

return;
}

void ArbitraryArithmetic::operator %=(const ArbitraryArithmetic &n){

	ArbitraryArithmetic r( *this );

	r /= n;
	*this = r.getremainder();

return;
}
ExtendedArithmetic.h
Code:
#ifndef EXT_AR_H
#define EXT_AR_H

/*
infinite-precision arithmetic class
by SCHiM
*/

class ArbitraryArithmetic{

long MyLength;
unsigned __int64 Remainder;
unsigned char* Number; 

public:
//constructor
ArbitraryArithmetic(long Lenght, unsigned __int64 n);
ArbitraryArithmetic( ArbitraryArithmetic &);

~ArbitraryArithmetic();

//debug/verification
void print();

//information
long getsize() const;
unsigned __int64 getremainder() const;
unsigned char* getnumber() const;
unsigned __int64 *touint64();

//support operators
void shift( int numdigits );
void bitshift( int bits );
void trim( int numdigits );
void chop( int numdigits );
unsigned __int64 getremainder();

int Compare(unsigned __int64 n) const;
int Compare(const ArbitraryArithmetic &) const;

//assignment operators
void operator = (unsigned __int64 n);
void operator = (const ArbitraryArithmetic &);

void operator -= (unsigned __int64 n);
void operator -= (const ArbitraryArithmetic &);

void operator += (unsigned __int64 n);
void operator += (const ArbitraryArithmetic &);

void operator *= ( __int64 n);
void operator *= (const ArbitraryArithmetic &);

void operator /= (const __int64 n);
void operator /= (const ArbitraryArithmetic &);

void operator %= (const __int64 n);
void operator %= (const ArbitraryArithmetic &);

//comparason operators
bool ArbitraryArithmetic::operator == (unsigned __int64 n) const {return Compare(n) == 0;}
bool ArbitraryArithmetic::operator != (unsigned __int64 n) const {return Compare(n) != 0;}
bool ArbitraryArithmetic::operator >  (unsigned __int64 n) const {return Compare(n) >  0;}
bool ArbitraryArithmetic::operator >= (unsigned __int64 n) const {return Compare(n) >= 0;}
bool ArbitraryArithmetic::operator <  (unsigned __int64 n) const {return Compare(n) <  0;}
bool ArbitraryArithmetic::operator <= (unsigned __int64 n) const {return Compare(n) <= 0;}

bool ArbitraryArithmetic::operator == (const ArbitraryArithmetic &n) const {return Compare(n) == 0;}
bool ArbitraryArithmetic::operator != (const ArbitraryArithmetic &n) const {return Compare(n) != 0;}
bool ArbitraryArithmetic::operator >  (const ArbitraryArithmetic &n) const {return Compare(n) >  0;}
bool ArbitraryArithmetic::operator >= (const ArbitraryArithmetic &n) const {return Compare(n) >= 0;}
bool ArbitraryArithmetic::operator <  (const ArbitraryArithmetic &n) const {return Compare(n) <  0;}
bool ArbitraryArithmetic::operator <= (const ArbitraryArithmetic &n) const {return Compare(n) <= 0;}

};

#endif
"unsigned char* nPtr = (unsigned char*) &n" could lead to undefined behavior on certain systems, you should consider taking use of bitwise operations instead.

Good job though.
plz update your add and reduce funtions. loooks pretty ugly.
here is my example written ~2 years ago in asm(gas) + function prototype in C
Code:
globl add_gcc
  .type add_gcc, @function
  add_gcc: # add_gcc(int1024* dest, int1024* arg1, int1024* arg2)
	   # for example
   pushq %rbp #enter - the same
   movq %rsp, %rbp #creating stack frame
  

   #movq 16(%rbp), %rdi
   movq %rdx, %rbx #pointer 
   #movq 24(%rbp), %rsi

   movq $16, %rcx
   clc
     loop1: 
       lodsq
       adcq  (%rbx),%rax
       leaq 8(%rbx), %rbx
       stosq
       loop loop1
     end_loop1:

   movq %rbp, %rsp
   popq %rbp
   ret
  .size add_gcc, . - add_gcc
Code:
#define _high 1024/(8*sizeof(int))
typedef struct {
	int data[_high+1];
} int1024;
extern int add_gcc(int1024* dest, const int1024* arg1, const int1024* arg2) ;
or another C sample
Code:
int1024 add(const int1024 a, const int1024 b){
	int1024 result;
	char inc;

	result.data[0]=0;
	for(int i =0; i<_high; ++i){
			result.data[i]=a.data[i]+b.data[i] + inc;
			inc=(max(a.data[i], b.data[i])>=result.data[i])&&(b.data[i])&&(a.data[i]);
	}

	return result;
	
}
u should probably use SSE2 for higher lengths, and AVX if ur going pass 256 bit and it supported cause this will murder performance pass an amount.

Maybe u can use it to benchmark CPUs low lvl arithmetics.
Posts 1–8 of 8 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?