高精度算法库

  初始化:bign a=2,b = 1335235235,c = "-4335";

  支持+,-,*,/运算,已经重载运算符,可以直接a+b,a-b,a*b,a/b,但不可以a+2,a+b+c。支持标准输入输出流输出。

  支持比较 < <= > >= == !=,支持位移<< >>(以10为单位),支持取反 !

/*
 * bign.cpp
 * 高精度算法库
 */

#include <cstring>
#include <iostream>
using namespace std;

#define MAXN 1000

struct bign
{
	int len;
	bool f;
	short s[MAXN];

	/* 构造函数 */
	bign()
	{
		memset(s,0,sizeof(s));
		f = false;	
		len = 0;
	}
	bign(const char* num){ *this = num; }
	bign(int num){ *this = num; }
	bign(long num){ *this = num; }
	bign(long long num){ *this = num; }
	bign(const bign &a)
	{
		len = a.len;
		f = a.f;
		for(int i=0;i<a.len;i++)
			s[i] = a.s[i];
	}

	/* =重载1,字符串赋值*/
	bign operator = (const char* num)
	{
		int i=0,index;
		index = len = strlen(num);

		if(num[0] == '-')
		{
			f = true;
			len--;
		}
		while(i<len)
		{
			s[i++] = num[--index] - '0';
		}
		
		return *this;
	}
	/* =重载2,整形赋值 */
	bign operator = (int num)
	{
		len = 0;
		f = false;
		if(num < 0)
		{
			f = true;
			num = -num;
		}
		while(num)
		{
			s[len++] = num%10;
			num /= 10;
		}

		return *this;
	}	
	/* =重载3,长整形赋值 */
	bign operator = (long num)
	{
		len = 0;
		f = false;
		if(num < 0)
		{
			f = true;
			num = -num;
		}
		while(num)
		{
			s[len++] = num%10;
			num /= 10;
		}

		return *this;
	}	
	/* =重载4,长长整形赋值 */
	bign operator = (long long num)
	{
		len = 0;
		f = false;
		if(num < 0)
		{
			f = true;
			num = -num;
		}
		while(num)
		{
			s[len++] = num%10;
			num /= 10;
		}

		return *this;
	}	
	/* =重载5,复制 */
	void operator = (const bign &a)
	{
		len = a.len;
		f = a.f;
		for(int i=0;i<a.len;i++)
			s[i] = a.s[i];
	} 

	/* 输出字符数组 */
	void str(char* arr,int n)
	{
		int i,j=0;
		if(f) arr[j++] = '-';
		for(i=0;i<n-1;i++)
		{
			if(len-i > 0)
			{
				arr[j++] = '0' + s[len-i-1];
			}			
			else
			{
				arr[j] = '\0';
				break;
			}
		}
	}
		
	bool cmp(bign* a,bign* b)
	{
		if(a->len != b->len) return a->len<b->len;
		for(int i=a->len-1;i>=0;i--)
			if(a->s[i] != b->s[i]) return a->s[i] < b->s[i];
		return false;
	}

	bool operator < (bign& b)
	{
		if(f && !b.f) 			return true;			// a<0,b>0 ---> a<b
		else if(!f && b.f) 		return false;			// a>0,b<0 ---> !a<b
		else if(f && b.f) 		return !cmp(this,&b);	// a<0,b<0 ---> !|a|<|b|
		else					return	cmp(this,&b);	// a>0,b>0 ---> |a|<|b|
	}
	bool operator > (bign& b) { return b<*this; }
	bool operator <= (bign& b) { return !(b<*this); }
	bool operator >= (bign& b) { return !(*this < b); }
	bool operator != (bign& b) { return (b < *this) || (*this < b); }
	bool operator == (bign& b) { return !(*this != b); }

	bign operator !() { bign a = *this; a.f = !a.f; return a;}
	// 加法函数,纯绝对值相加
	bign add(bign& a,bign& b)
	{
		bign c;
		c.len = 0;
		int maxlen = max(a.len,b.len);
		int i=0,g=0;

		for(i=0,g=0;g || i<maxlen;i++)		// i 位标号,g进位数
		{
			int x = g;
			if(i<a.len) x += a.s[i];
			if(i<b.len) x += b.s[i];
			c.s[c.len++] = x%10;
			g = x/10;
		}
	
		return c;
	}

	// 减法函数,纯绝对值相减,应避免不够减的情况
	bign minus(bign& a,bign& b)
	{
		bign c;
		int i,g;
		for(i=0,g=0;i<a.len;i++)
		{
			int x = a.s[i] + g;
			if(i<b.len) x -= b.s[i];
			
			if(x < 0)
			{
				c.s[c.len++] = x + 10;
				g = -1;
			}
			else
			{
				c.s[c.len++] = x;
				g = 0;
			}
		}
		while(c.len-- && c.s[c.len] + g == 0) c.s[c.len] = 0;
		c.len++;

		return c;
	}


	/* 重载运算符 */
	bign operator << (unsigned int i)
	{
		bign c;
		c.len = len+i<MAXN ? len+i : MAXN;
		
		int j=len,k=c.len;
		while(k>0)
			c.s[--k] = s[--j];

		return c;
	}
	bign operator >> (unsigned int i)
	{
		bign c;
		c.len = len-i>=0 ? len-i : 0;

		int k=0,j=i;
		while(k<c.len)
			c.s[k++] = s[j++];

		return c;
	}

	
	bign operator + (bign& b)
	{
		bign c;

		/* 如果有负数,转化成减法 */
		if((this->f && !b.f) || (!this->f && b.f))		
		{
			if(cmp(&b,this))
			{
				c = minus(*this,b);
				c.f = this->f;
			}
			else
			{
				c = minus(b,*this);
				c.f = b.f;
			}
		}
		/* 两个正数绝对值相加,或两个正数绝对值相加 */
		else
		{
			c = add(*this,b);
			c.f = this->f;
		}
		
		return c;
	}

	bign operator - (bign& b)
	{
		b.f = !b.f;
		bign c = *this + b;
		b.f = !b.f;

		return c;
	}		


	bign operator * (bign& b)
	{
		int i,j;
		bign c;
		c.f = (f != b.f);					// 同号得正,异号得负

		for(i=0;i<len;i++)					// 下面的因数
		{
			// 每位依次乘以b
			for(j=0;j<b.len;j++)			// 上面的因数
			{
				// 错位相加
				int x = c.s[i+j] + s[i]*b.s[j];
				c.s[i+j] = x%10;				// 当前位数字
				if(x/10)
				{
					c.s[i+j+1] += x/10;				// 进位
					c.len = max(c.len,i+j+2);
				}
			}
		}

		if(c.s[i+j+1] >= 10)
		{
			c.s[c.len++] = c.s[i+j+1]%10;
			c.s[i+j+1] %= 10;			
		}

		return c;
	}				


	
	bign operator / (bign&b)
	{
		int i,j;
		bign c;
		bign a = *this;

		c.f = (a.f != b.f);					// 同号得正,异号得负

		for(i=a.len-b.len;i>=0;i--)			// 被除数前面至少有除数的位数
		{
			bign try_num;
			bign bb = b<<i;
			for(j=0;j<10;j++)
			{
				try_num = try_num + bb;		// 试商
				if(cmp(&a,&try_num)) break;
			}
			try_num = try_num - bb;

			if(j)
			{
				c.len = max(c.len,i+1);
				c.s[i] = j;
				a = minus(a,try_num);
			}
		}

		return c;
	}
};

/* 输入输出流 */
istream& operator >> (istream &in,bign &x)
{
	char s[MAXN];
	in>>s;
	x = s;
	return in;
}
	
ostream& operator << (ostream &out,bign &x)
{
	char s[MAXN];
	x.str(s,MAXN);
	out<<s;
	return out;	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值