All pastes #1933764 Raw Edit

ExpNum

public text v1 · immutable
#1933764 ·published 2010-09-05 17:06 UTC
rendered paste body
#include <iostream.h>
#define tabl '\t'
class ExpNum
{	public:
	short unsigned int mant[30];
	char sign;
	int exp;
	short unsigned int mant_len;
	ExpNum(char* exp_str = "+0.0E+0")
	{	sign = *exp_str == '+' ? '+' : '-';
		char* exp_ptr = exp_str + 3;	
		mant_len = 0;
		unsigned int i = 0;
		while ((*exp_ptr != 'E') && (*exp_ptr != 'e'))
		{	mant[i++] = int(*exp_ptr++) - 48;
			mant_len++;
		}
		for (short int i = mant_len; i < 30;)
			mant[i++] =0;
		exp_ptr++;
		if ('-' == *exp_ptr++) 
			exp = -1;
		else
			exp = 1;	
		exp *= int(*exp_ptr++) - 48;
		while (*exp_ptr != '\0')
		{	exp *= 10;
			if (exp > 0) 
				exp += int(*exp_ptr++) - 48;
			else
				exp -= int(*exp_ptr++) - 48;
		}
		Normalize();
	}
	void Normalize()
	{	short unsigned int *p = &mant[29];
		short unsigned int mant_tmp[30];
		short unsigned int mant_dif = 0;
		mant_len = 30;
		while ((!*p--) && (mant_len > 1))
			mant_len--;
		if (mant[0] == 0)
		{	while ((mant[mant_dif] == 0) && (mant_dif < 30))
				mant_dif++;
			if (mant_dif == 30) 
			{	exp = 0;
				mant_len = 0;
			}
			else
			{	exp -=mant_dif;
				mant_len -= mant_dif;
				for (short int i = 0; i < 30 - mant_dif; i++)		
					mant[i] = mant[i + mant_dif];
				for (short int i = 30 - mant_dif; i < 30; i++)
					mant[i] = 0;
			}
		}
	}
};	

const ExpNum zero("+0.0E+0");

ostream& operator << (ostream& out,ExpNum b);

ExpNum  operator >> (istream& in, ExpNum& a);

bool operator > (ExpNum a, ExpNum b);

bool operator == (ExpNum a, ExpNum b);

bool operator < (ExpNum a, ExpNum b); 

bool operator <= (ExpNum a, ExpNum b); 

bool operator >= (ExpNum a, ExpNum b); 

bool operator != (ExpNum a, ExpNum b); 

ExpNum operator - (ExpNum a, ExpNum b);
	
ExpNum operator -=(ExpNum a, ExpNum b);

ExpNum operator +=(ExpNum a, ExpNum b);

ExpNum operator /=(ExpNum a, ExpNum b);
	
ExpNum operator + (ExpNum a, ExpNum b);

ExpNum operator / (ExpNum a, ExpNum b);

ExpNum ABSE(ExpNum a);
/*////////////////////////////////////////////////////////////////////////////*/
bool operator < (ExpNum a, ExpNum b)
{	return !((a == b) || (a > b));	
}

bool operator <= (ExpNum a, ExpNum b)
{	return (a < b) || ( a == b);
}

bool operator >= (ExpNum a, ExpNum b)
{	return (a > b) || (a == b);
}

bool operator == (ExpNum a, ExpNum b)
{	bool l = true;
	short int i = -1;
	while ((++i < 29) && l)
		l = (a.mant[i] == b.mant[i]);
	return (a.exp == b.exp) && (a.sign == b.sign) && l;
}

bool operator != (ExpNum a, ExpNum b)
{	return !(a == b);
}

bool operator > (ExpNum a, ExpNum b)
{	bool l;
	if (a.sign == b.sign)
	{	if (a.exp > b.exp)
			l = (a.sign == '+');
		else
		{	if (a.exp == b.exp)
			{	short int i = 0;
			
	while ((i < 30) && (a.mant[i] == b.mant[i])) i++;
				if (a.mant[i] > b.mant[i])
					l = a.sign == '+';		
			}		
		}
	}
	else
		l = (a.sign == '+');
	return l;
} 

ExpNum operator - (ExpNum a, ExpNum b)
{	ExpNum c;
	if (a == b) 
	{	c.exp = 0;
		for (short int i = 0 ; i < 30;)
			c.mant[i++] =0;
		c.sign = '+';
		c.mant_len = 1;
	}
	else
	if (a.sign == b.sign)
	{	if (ABSE(a) < ABSE(b))
		{	c = b;
			b = a;
			a = c;
			a.sign = '-';
		}
		bool mant_buf = 0;
		short unsigned int mant_dif = a.exp - b. exp;
		short  int mant_new[31];
		for (short int i = 0; i < 30; i)
		{	mant_new[i++] = 0;
		}
		if (mant_dif + a.mant_len > 30)
			mant_buf =1;
		for (short int i = 29; i >=0;)
		{	mant_new[i] = a.mant[i] - ( (i >= mant_dif ) ?  b.mant[i - mant_dif] : 0) - mant_buf;
			mant_buf = mant_new[i] < 0 ? 1 :0;
			if (mant_buf) mant_new[i] += 10;
			i--;
		}
		mant_dif = 0;
		short int *p1 = mant_new;
		while (!*p1++)
		{	a.exp--;
			mant_dif++;
		}
		delete(p1);
		for (short int i = 0; i < 29; i )
		{	c.mant[i] = mant_new[i + mant_dif];
			i++;
		}
		c.sign = a.sign;
		c.exp = a.exp;
		c.mant_len = 30;
		short unsigned int *p2 = &c.mant[29];
		while (!*p2--)
			c.mant_len--;
	}
	else
		if (a.sign = '+')
		{	b.sign = '+';
			c = a + b;
		}
		else
		{	b.sign = '-';
			c = a + b;
		}
	return c;
}

ExpNum operator + (ExpNum a, ExpNum b)
{	ExpNum c;
	if (a.sign == b.sign)
	{	if (b.exp > a.exp)
		{	c = b;
			b = a;
			a = c;
		}
		short unsigned int mant_new[31];
		short unsigned int mant_buf = 0;
		short unsigned int mant_dif = a.exp - b. exp;
		for (short int i = 0; i < 31; i++)
		{	mant_new[i] = 0;
		}
		for (short int i = 29; i >= mant_dif; i-- )
		{	mant_buf += a.mant[i] + b.mant[i - mant_dif];
			mant_new[ i + 1] = mant_buf % 10;
			mant_buf /= 10;
		}
		for (short int i = mant_dif - 1; i >= 0; i-- )
		{	mant_buf += a.mant[i];
			mant_new[i + 1] = mant_buf % 10;
			mant_buf /= 10;
		}
		if (mant_buf) 
		{	mant_new[0] = mant_buf;
			mant_dif = 0;
			a.exp++;
		}
		else
			mant_dif = 1;
		for (short int i = 0; i < mant_dif; i++)
			mant_new[i] = 0;
		short unsigned int *p1 = c.mant;
		short unsigned int *p2 = mant_new + mant_dif;
		for (short int i = 0; i < 30; i++ )
			*p1++ = *p2++;
		delete(p2);
		delete (p1);
		short int i = 29;
		c.mant_len = 30;
		while (!c.mant[i--])
			c.mant_len--;
		c.sign = a.sign;
		c.exp = a.exp;
	}
	else
	if (a.sign == '+')
	{	b.sign = '+';
		c = a - b;
	}
	else
	{	a.sign = '+';
		c = b - a;
	}
	return c;
}

ExpNum operator / (ExpNum a, ExpNum b)
{	ExpNum c;
	ExpNum buf = zero;
	unsigned int a_ct = 0;
	bool first = 1;
	short unsigned int *p1;
	c.mant_len = 0;
	c.sign = a.sign == b.sign ? '+' : '-';
	c.exp = a.exp - b.exp;
	b.exp = b.mant_len;
	while ((++c.mant_len < 31) && !((a_ct >= a.mant_len) && (buf == zero)))
	{	buf.Normalize();
		while (buf < b)
		{	buf.exp ++;
			if (buf.mant_len < 30)
			{
			if (a_ct < a.mant_len ) 
				buf.mant[buf.mant_len++] =  a.mant[a_ct++];
			else
				buf.mant[buf.mant_len++] = 0;
			}
			if ((buf < b) && !first)
				c.mant[c.mant_len++] = 0;
		}	
		buf.Normalize();
		first = 0;
		while (buf >= b)
		{	buf  = buf - b;
			c.mant[c.mant_len - 1]++;			
			cout << ' ';
		}
		buf.Normalize();		
	}
	c.Normalize();
	return c;
}

ExpNum operator -=(ExpNum& a, ExpNum b)
{	a = a - b;
	return a;
}

ExpNum operator +=(ExpNum& a, ExpNum b)
{	a = a + b;
	return a;
}

ExpNum operator /=(ExpNum& a, ExpNum b)
{	a = a / b;
	return a;
}

ExpNum  operator >> (istream& in, ExpNum& a)
{	char a_str[41];
	in >> a_str;
	ExpNum c(a_str);
	a = c;
	return c;
}

ostream& operator << (ostream& out,ExpNum a)
{	out << a.sign << "0.";
	if (a.mant_len == 0)	
		out << '0';
	else
		for (short unsigned int i = 0; i < a.mant_len;)
			out << a.mant[i++];
	out.setf(ios::showpos);
	out << "E" << a.exp;
	return out;
	out.unsetf(ios::showpos);
}

ExpNum ABSE(ExpNum a)
{	a.sign = '+';
	return a;
}