高精度模板---加、减、乘、除(非负数)

U p d 2018.10.2 : Upd_{2018.10.2}: Upd2018.10.2:加入除法,更新了部分代码(统一用构造函数初始化);忽略掉了减法负数的判断


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;

struct Bigint
{
   // bool f; // 0:+  1; -   符号判断(可忽略)
    int size; //数位
    int num[20000]; //数值
    
    // 重载: 与函数类似,返回值类型 + operator + 重载符号 + ( 运算符右边的元素类型 ) 
    // ps: 1.可以重载多个相同的运算符,不过要保证不完全相同 即  算符右边的元素类型不同( 高精*高精  高精*单精 ) 
    //     2.本模板仅限于非负数之间的操作  , 如有负数,需加一些判断(ans正负 , 正+负==正- |负| )和处理(符号处理)
    //  3.对于除法而言,若要同时得到商和余数,可以考虑返回一个pair之类的
    
   inline Bigint()
   {
		memset(num, 0, sizeof(num));
		size = 0;
	}
	
	bool operator < (const Bigint &b) const
	{
		if(size ^ b.size) return size < b.size;
		for(int i = size; i; --i)
		if(num[i] ^ b.num[i])
			return num[i] < b.num[i];
		return 0;
	}

	bool operator == (const Bigint &b) const
	{
		if(size ^ b.size) return 0;
		for(int i = size; i; --i)
		if(num[i] ^ b.num[i])
			return 0;
		return 1;
	}
	
	bool operator <= (const Bigint &b) const
	{
		if(size ^ b.size) return size < b.size;
		for(int i = size; i; --i)
		if(num[i] ^ b.num[i])
			return num[i] < b.num[i];
		return 1;
	}

//--------------------------------------------------------------
	
    Bigint operator + (const Bigint &b) //const + & 定义的元素不可更改 
    { // 高精+高精 
        Bigint c; //加入构造函数,自动初始化 
        int &s = c.size;
        int r = 0;
        s = (size > b.size ? size : b.size);
        for(int i = 1; i <= s; ++i)
        {
            r += num[i] + b.num[i];
            c.num[i] = r % 10;
            r /= 10;
        }
        for(; r; r /= 10)
            c.num[++s]=r%10;
        return c;
    } 
//--------------------------------------------------------------
    
	Bigint operator - (const Bigint &b)
	{//高精 - 高精
		//default: (*this) >= b
		Bigint c;
		int r = 0;
		int &s = c.size;
		s = size;
		for(int i = 1; i <= size; ++i)
		{	
			r += num[i] - b.num[i];
			if(r < 0)
			{	
				c.num[i] = r + 10;
				r = -1;
			}else
			{
				c.num[i] = r;
				r = 0;    // 重载: 与函数类似,返回值类型 + operator + 重载符号 + ( 运算符右边的元素类型 ) 
    // ps: 1.可以
			}
		}
		
		for(; s > 1 && !c.num[s]; --s);
		return c;
	}
//--------------------------------------------------------------	

    //对于乘法 当数值为1时,考虑删除前导0
	Bigint operator * (const int &b)
	{//高精 * 单精
		if(b == 1) return (*this);
		Bigint c;
		int r = 0;
		int &s = c.size;
		s = size;
		
		for(int i = 1; i <= size; ++i, r/= 10)
		{
			r += num[i] * b;
			c.num[i] = r % 10;
		}
		for(; r; r /= 10)
			c.num[++s] = r % 10;
		
		for(; s > 1 && !c.num[s]; --s);
		return c;
	}


	Bigint operator * (const Bigint &b)
	{//高精 * 高精
		if(b.size == 1 && b.num[1] == 1) return (*this);
		if(size == 1 && num[1] == 1) return b;
		Bigint c;
		int r = 0;
		int &s = c.size;
		
		for(int i = 1, p; i <= size; ++i)
		{
			p = i;
			for(int j = 1; j <= b.size; ++j, ++p, r/= 10)
			{
				r += num[i] * b.num[j] + c.num[p];
				c.num[p] = r % 10;
			}
			--p;
			for(; r; r /= 10)
			{
				r += c.num[++p];
				c.num[p] = r % 10;
			}
			if(p > s) s = p;
		}
		
		for(; s > 1 && !c.num[s]; --s);
		return c;
	}
//--------------------------------------------------------------	

	Bigint operator / (const int &b)
	{//高精 / 单精 -- 剩下的r即为余数
		if(b == 1) return (*this);
		
		Bigint c;
		int r = 0;
		int &s = (c.size);
		s = -1;
		
		for(int i = size; i; --i)
		{
			r = r * 10 + num[i];
			if(r >= b)
			{
				if(s == -1) s = i;
				c.num[i] = r / b;
				r -= b * c.num[i];
			}
		}

		return c;
	}


	inline int div_cmp(const Bigint &b) // 比较
	{
		if(size < b.size) return 1;
		for(int i = 0; i < b.size; ++i)
		if(num[size - i] ^ b.num[b.size - i])
			return num[size - i] < b.num[b.size - i];
		return 0;
	}
	
	inline Bigint div_mul_10(int t) //×10优化
	{
		if(!t) return (*this); 
		Bigint c;
		
		c.size = size + t;
		for(int i = 1; i <= size; ++i)
			c.num[i + t] = num[i];
		return c;
	}
	
	Bigint operator / (Bigint b)
	{//高精 / 高精  -- 上面两个函数用来优化
		// c为商,a为余数
		if(b.size == 1 && b.num[1] == 1) return (*this);
		
		Bigint a = (*this), c, tmp, r;
		int &s = c.size;
		s = -1;
		
		for(int len, t;;)
		{
			len = a.size - b.size - a.div_cmp(b);
			if(len < 0) break;
			tmp = b.div_mul_10(len);
			
			t = 0;
			for(;tmp <= a; a = a - tmp, ++t);
			
			if(s == -1 && t) s = len + 1;
			
			c.num[len + 1] = t;
		}
		return c;
	}

//--------------------------------------------------------------

    inline void turn (int x) //转化 (看情况,可改 long long)
    {
        for(;x;x/=10)
            num[++size]=x%10;
    } 
    
    inline void in() //读入 
    {
        char c = getchar();
        for(;'0' > c || c > '9'; c = getchar());
        for(;'0' <= c && c <= '9'; c = getchar())
            num[++size] = c - '0';
        for(int l = 1, r = size; l < r;)
            swap(num[l++], num[r--]);
    }
    
    inline void out() //输出 
    {
        //if(f) putchar('-'); 
        for(int i = size; i; --i)
            putchar(num[i] + '0');
        putchar('\n');//自动换行 , 可删去 
    }
    
};
 //注意0的位数一定不能为0,否则不能输出 

Bigint a,b,c;

int main()
{ //仅供参考,自行使用
    printf("test:\n");
    printf("请输入两串数字:\n");
    a.in();
    b.in();
    
    printf("a+b: "); (a+b).out();
    printf("a-b: "); (a-b).out();
    printf("a*b: "); (a*b).out();
    printf("a;"); a.out();
    printf("b: "); b.out();
    putchar('\n');
    int x;
    printf("请输入一个int范围内的数:\n");
    scanf("%d",&x);
    c.turn(x);
    printf("c: "); c.out();    
    printf("a*x: "); (a*x).out();   
    printf("a*c: "); (a*c).out();     
    //system("pause");
    return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值