8- High precision calculation (addition)

We know that in C language and C++, there is a clear upper limit for the maximum value that can be stored. But sometimes we need to calculate some numbers with relatively large values: for example, the addition and subtraction of numbers with 1000 and 10000 digits. At this time, we need to use a new calculation method.

Here is the introduction of high-precision big data calculations, which can be used to calculate numbers with a large number 10^{6}of digits. Its main idea is to use arrays to store the number of digits of large numbers, and use the characteristics of calculation rules to perform calculations. Let's take a look at addition.

The first is the processing process of big data. If our general long type variable cannot store data, we consider using an array or vector type container to store it. For example, the number 1598, we can use an array to store it upside down, arr[0] stores the ones first, and then stores the following digits sequentially (as shown in the lower figure below). There is an advantage in this way, because when we do addition operations, the largest bit may be advanced by one bit. If we choose arr[0] as the largest bit at this time, then we need to move the entire array backward by one bit ( (as shown in the upper figure below).

After understanding the way of storing large numbers, let's first recall the operation process of addition: for example, we have two arrays A, B, and C, which store the data on each bit of the large numbers a and b, and C is the storage The result is an array of individual digit values. Then we start with the ones digit corresponding to the two arrays, and after calculating the ones digit, see if it needs to be carried to the tens digit, and so on. Because the problem of carry is also considered, we simply define that each digit of C is (A[i]+B[i]+t)%10, where t is the number of digits carried forward from the previous digit. The ones digit is t or 0. For example, the following formula: A={9, 3, 1}, B={7, 3}. C[0]=(A[0]+B[0]+0)%10=16%10=6; C[1]=(A[1]+B[1]+1)%10=7% 10=7; C[2]=(A[2]+0)%10=1%10=1. So C is {6, 7, 1}.

According to this idea, we can write the code for the addition of large numbers. Here, the container vector is used for convenience:

The overall code is divided into two sections: the first section is to process data, and the second section is to calculate large numbers.

Let’s look at processing data first: we use string type variables to receive data, so if we want to change to a vector container to store each bit, we need to convert each number in the string into an int type of data and store it in A/ In container B. Numeric characters and numbers have a corresponding relationship: x (char type) - '0' = x (int type). In this way, a container that stores large data a and b can be obtained.

	for (int i = a.size()-1; i >= 0; i--) A.push_back(a[i] - '0');
	for (int i = b.size()-1; i >= 0; i--) B.push_back(b[i] - '0');

Next is the part of the core large number calculation:

We pass the two containers that need to be added into the function, and then use a loop to add each bit of the two containers. For example: add two numbers: 120 and 3, and their result is 123. There is no operation for 1 and 2 in 120 here, because 3 only needs to be operated with the ones in 120. In the same way, when adding two numbers, either the two numbers are exactly equal, or one has a higher digit than the other. At this time, the condition for the addition to stop is that the highest digit of the number with the higher digit has been calculated. So the end condition of the loop is when it is added to the largest bit of A and B, and the addition stops at this time. So there are the following stop judgment conditions.

 i < A.size() || i < B.size()

 Then let's look at the two ifs inside. These two ifs mean that we are not sure whether A or B has a higher number of digits, so let the calculation of the number of digits with a lower number of digits be stopped after the calculation is completed, while the calculation of the number of digits with a higher number of digits will continue. Then take the added data modulo ten to obtain the results of the corresponding bits of A and B, assign them to C, and finally divide t by 10 to obtain the carry. The last if(t) is to judge whether the addition of two numbers needs to be incremented, and to judge whether it is necessary to enter 1 next time after the final operation, that is, to judge whether t is 1. If it is, add 1, if it is not, it will not be processed.

vector<int> add(vector<int>& A, vector<int>& B)
{
	vector<int> C;
	int t = 0;
	for (int i = 0; i < A.size() || i < B.size(); i++)
	{
		if (i<A.size())t += A[i];
		if (i<B.size())t += B[i];
		C.push_back(t % 10);
		t = t / 10;
	}
	if (t) C.push_back(1);
	return C;
}

Overall code: 

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


vector<int> add(vector<int>& A, vector<int>& B)
{
	vector<int> C;
	int t = 0;
	for (int i = 0; i < A.size() || i < B.size(); i++)
	{
		if (i<A.size())t += A[i];
		if (i<B.size())t += B[i];
		C.push_back(t % 10);
		t = t / 10;
	}
	if (t) C.push_back(1);
	return C;
}




int main()
{
	string a, b;
	vector<int> A, B;
	cin >> a >> b;
	for (int i = a.size()-1; i >= 0; i--) A.push_back(a[i] - '0');
	for (int i = b.size()-1; i >= 0; i--) B.push_back(b[i] - '0');
	auto C = add(A, B);

	for (int i = C.size()-1; i >= 0; i--) cout << C[i];

	return 0;
}

Guess you like

Origin blog.csdn.net/m0_61151031/article/details/127600669