zoukankan      html  css  js  c++  java
  • 非负数高精度

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int MAX_LEN = 1001, CARRY = 4, BASE = 10000;
    
    struct BigInt
    {
    private:
    	int A[MAX_LEN];
    	int Len;
    
    public:
    	void Clear()
    	{
    		memset(A, 0, sizeof(A));
    		Len = 0;
    	}
    
    	void Set(int x)
    	{
    		Clear();
    		while (x)
    		{
    			A[Len++] = x%BASE;
    			x /= BASE;
    		}
    		while (Len > 0 && !A[Len])
    			Len--;//规定动作不要改
    	}
    
    	BigInt() { Clear(); }
    	BigInt(int x) { Set(x); }
    
    
    	void Read(char *s)
    	{
    		Clear();
    		int cur = 0, pos = 0, pow = 1;
    		for (int i = strlen(s) - 1; i >= 0; i--)//易忘点:倒序循环。因为位数小的数字在右边。//易忘点:-1
    		{
    			cur += (s[i] - '0')*pow;
    			pow *= 10;//易忘点
    			if (++pos == CARRY)
    			{
    				A[Len++] = cur;
    				cur = pos = 0;
    				pow = 1;
    			}
    		}
    		if (!pos)//最好按照pos来判断。
    			Len--;
    		else
    			A[Len] = cur;
    	}
    
    	void Read()
    	{
    		char s[MAX_LEN*CARRY];
    		scanf("%s", s);
    		Read(s);
    	}
    
    	void Print()
    	{
    		printf("%d", A[Len]);//易忘点。否则输出的数字前面多了几个0.
    		for (int i = Len - 1; i >= 0; i--)
    			printf("%0*d", CARRY, A[i]);//易忘点:%0*d。否则每一位前面的几个0没有输出。
    		printf("
    ");
    	}
    
    
    	BigInt operator = (const BigInt &a)
    	{
    		memcpy(A, a.A, sizeof(A));
    		Len = a.Len;
    		return *this;
    	}
    
    	bool operator < (const BigInt &a)
    	{
    		if (Len != a.Len)
    			return Len < a.Len;
    		for (int i = Len; i >= 0; i--)
    			if (A[i] != a.A[i])
    				return A[i] < a.A[i];
    		return false;
    	}
    
    
    	BigInt operator += (const BigInt &a)
    	{
    		Len = max(Len, a.Len);
    		for (int i = 0; i <= max(Len, a.Len); i++)
    		{
    			A[i] = (A[i] + a.A[i]);
    			A[i + 1] += A[i] / BASE;//易忘点:不是(A[i]+a.A[i])/BASE,因为A[i]是修改后的值
    			A[i] %= BASE;//易忘点:不要与第一句写在一起。//易忘点:此句和上一句/和%不要写反了
    		}
    		if (A[Len + 1])
    			Len++;
    		return *this;
    	}
    
    	BigInt operator + (const BigInt &a)
    	{
    		BigInt ans = *this;
    		return ans += a;
    	}
    
    
    	BigInt operator -= (const BigInt &a)
    	{
    		for (int i = 0; i <= Len; i++)
    		{
    			A[i] -= a.A[i];
    			if (A[i] < 0)
    			{
    				A[i] += BASE;
    				A[i + 1]--;//易忘点:借位是-,不是+
    			}
    		}
    		while (Len > 0 && !A[Len])//易忘点:Len>0
    			Len--;
    		return *this;
    	}
    
    	BigInt operator - (const BigInt &a)
    	{
    		BigInt ans = *this;
    		return ans -= a;
    	}
    
    
    	BigInt operator *= (const BigInt &a)
    	{
    		BigInt b = *this;
    		Clear();
    		Len = a.Len + b.Len;//以上3句 易忘点:乘法不是在原有乘数的基础上修改出来的,而是一个全新的数字
    		for (int i = 0; i <= a.Len; i++)
    		{
    			for (int j = 0; j <= b.Len; j++)
    			{
    				A[i + j] += a.A[i] * b.A[j];//易忘点:a. , b.//易忘点:+=,而不是=。相乘的结果最后是要累加的。
    				A[i + j + 1] += A[i + j] / BASE;//易忘点:A[i+j],而不是a.A[i]*b.A[j]
    				A[i + j] %= BASE;//易忘点:此句不可以与第一句结合在一起,因为第二句要用。
    			}
    		}
    		if (A[Len + 1])
    			Len++;
    		return *this;
    	}
    
    	BigInt operator * (const BigInt &a)
    	{
    		BigInt ans = *this;
    		return ans *= a;
    	}
    
    
    	BigInt operator /= (const int x)
    	{
    		for (int i = Len; i >= 0; i--)
    		{
    			if (i > 0)
    				A[i - 1] += A[i] % x * BASE;
    			A[i] /= x;//易忘点:此句并非在if的上面,否则if中的A[i]就是修改后的值了
    		}
    		while (Len > 0 && !A[Len])
    		//while(A[0]>0&&A[Len]<=0)
    			Len--;
    		return *this;
    	}
    
    	BigInt operator / (const int x)
    	{
    		BigInt ans = *this;
    		return ans /= x;
    	}
    
    	BigInt operator /= (const BigInt &a)
    	{
    		BigInt l, r = *this, one(1);//易忘点:r!=Len, l!=1(*this可能表示0)//易忘点:不能写one=1,因为声明时的=与重定义的=不是一个=
    		while (l < r)
    		{
    			BigInt mid = (l + r + one) / 2;
    			if (*this < (mid * a))//易忘点:<两边不要写反了,此判断说明当前的a选大了。
    				r = mid - one;
    			else
    				l = mid;
    		}
    		return *this = l;
    	}
    
    	BigInt operator / (const BigInt &a)
    	{
    		BigInt ans = *this;
    		return ans /= a;
    	}
    
    	bool IsZero()
    	{
    		return Len == 0 && A[0] == 0;
    	}
    };
    

      

  • 相关阅读:
    Spring Cloud
    如何修改容器时间而不改变宿主机时间?
    消息中间件 RabbitMQ 入门篇
    CentOS7下NFS服务安装及配置固定端口
    查看ssh有没有被黑的IP
    JVM常用命令和性能调优建议
    nfs高可用
    kafka集群部署以及单机部署
    OSGI企业应用开发(十三)OSGI Web应用开发(二)
    OSGI企业应用开发(十二)OSGI Web应用开发(一)
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8885855.html
Copyright © 2011-2022 走看看