C++ basic algorithm ② - high-precision multiplication and division calculations

C++ Basic Algorithm ①——High-precision addition and subtraction calculation

If you already know high-precision addition and subtraction, it will be much easier to look at multiplication and division. Then let's look at multiplication first. The multiplication rule is to multiply two numbers one by one and then add them to get the final result. In fact, it is to perform a multiplication operation before high-precision addition.

High-precision addition ideas:

  1. Store large numbers into strings ;
  2. Find the length by which two numbers are to be multiplied. The maximum length of the multiplication of two numbers will not exceed the sum of the lengths of the two numbers.len_max = len1+len2-1;
  3. Each character number of the string is stored in the array through ASCII conversion .
    Note that the low bit must exist at the beginning of the array: a[i] = s[len-i-1]-'0';
  4. Multiplication and carry calculation formula :
    ① c[i+j] += a[i] * b[j]
  5. Add carry to array c:
    ① c[i+1] += c[i]/10;
    ② c[i] %= 10;
  6. result overflow
  7. Reverse output results;

1. Multiply high precision by low precision

Enter a value, store it in an array, and convert it to an integer.

#include<iostream>
#include<string>
using namespace std;
string a;
int b[100],c;
int main(){
    
    
	cin >> a >> c;
	//把a 存储到 b里面去,a的最低位存储到b[0]
	int lena = a.size();
	for(int i=0; i<lena; i++){
    
    
		b[i] = a[lena-1-i] - '0';
	} 

Multiplication: 1234 * 5, we can know that 5 multiplies each number separately; that is, b[0] * 5, b[1] * 5, etc.….

//把c依次乘到b数组的每一位
	for(int i=0; i<lena; i++){
    
    
		b[i] *= c;
	} 

After multiplication, if the value of the array exceeds 9, it must be carried.

	//处理进位
	for(int i=0; i<lena; i++){
    
    
		b[i+1] += b[i]/10;
		b[i] %= 10;
	}

For example, 9999 * 9 = 89991, it has overflowed and we need to process it; finally remember to output the result in reverse.

//高位处理,对象是b[lena] ,利用数位分离的方法
	while(b[lena]){
    
    
		b[lena+1] = b[lena]/10;
		b[lena] %= 10;
		lena++;//这里容易漏掉 
	}
//反向输出 
	for(int i=lena-1; i>=0; i--){
    
    
		cout << b[i];
	} 
	return 0;
} 

High precision* Low precision complete code:

#include<iostream>
#include<string>
using namespace std;
string a;
int b[100],c;
int main(){
    
    
	cin >> a >> c;
	//把a 存储到 b里面去,a的最低位存储到b[0]
	int lena = a.size();
	for(int i=0; i<lena; i++){
    
    
		b[i] = a[lena-1-i] - '0';
	} 
	//把c依次乘到b数组的每一位
	for(int i=0; i<lena; i++){
    
    
		b[i] *= c;
	} 
	//处理进位
	for(int i=0; i<lena; i++){
    
    
		b[i+1] += b[i]/10;
		b[i] %= 10;
	} 
	//高位处理,对象是b[lena] ,利用数位分离的方法
	while(b[lena]){
    
    
		b[lena+1] = b[lena]/10;
		b[lena] %= 10;
		lena++;//这里容易漏掉 
	} 
	//反向输出 
	for(int i=lena-1; i>=0; i--){
    
    
		cout << b[i];
	} 
	return 0;
} 

Insert image description here


2. Multiply high precision by high precision

It's basically the same as before. The input is converted into an integer and stored in an array.

#include<iostream>
#include<string>
using namespace std;
string s1,s2;
int a[100],b[100],c[200];
int main(){
    
    
	cin>>s1>>s2;
	int len1 = s1.size(); 
	int len2 = s2.size(); 
	int len_max = len1+len2-1; //
	for(int i=0;i<len1;i++){
    
      
		a[i] = s1[len1-i-1]-'0'; 
	} 
	for(int i=0;i<len2;i++){
    
      
		b[i] = s2[len2-i-1]-'0';
	}

How do you find the total length?
1. Multiply two numbers (not considering 0). Generally, the total length is **[the sum of the lengths of the two numbers -1, the sum of the lengths of the two numbers]**. In this interval, I set len_max = len1+len2-1;

Vertical multiplication and summation

Insert image description here
Looking at it this way, the subscript of the a array is represented by i, and the subscript of the b array is represented by j. For the c array, we can see that c[1+0] = a[1]*b[0] + a[0]* b[1] ; Derivation: c[i+j] += a[i] * b[j].

// 乘法
	for(int i=0;i<len1;i++){
    
    
		for(int j=0;j<len2;j++){
    
    
			c[i+j] += a[i] * b[j]; 
		}
	}

After the multiplication, if the value of the c array exceeds 9, addition and carry will be performed.

	for(int i=0;i<len_max;i++){
    
    
		c[i+1] += c[i]/10;
		c[i] %= 10;
	}

After the carry is completed, check whether there is an overflow, and finally output the result in reverse.

//溢出处理,再加法进位一次
	while(c[len_max]){
    
    
		c[len_max+1] = c[len_max]/10;
		c[len_max] %= 10;
		len_max++;
	} 
//反向输出
	for(int i=len_max-1;i>=0;i--){
    
    
		cout<<c[i];
	} 

Insert image description here


3. High precision eliminates low precision

Insert image description here
As can be seen from the picture above, first 4 and 23 get along, that is, the highest digit is divided by 23. If the array is stored, a[0] is the highest bit.

#include<iostream>
#include<string>
using namespace std;
string s;
int a[1000],b,c[10000],x=0;
int main(){
    
    
	cin>>s>>b; 
	int len = s.size(); 
	for(int i=0;i<len;i++){
    
    
		a[i] = s[i]-'0'; //最高位存a[0]
	}

Insert image description here
How to get the integer 0 and the remainder 4?

整数:c[0] = a[0] / b
余数:? = a[0] % b

How do we get the integer 1 and the remainder 45?

整数:c[1] = (a[0]*10+a[1]) / b;
余数:? =  (a[0]*10+a[1]) % b;

a[0] * 10 We can represent it by x * 10; the remainder is represented by x.

	// 除法
	for(int i=0;i<len;i++){
    
    
		c[i] = (x*10+a[i]) / b;
		x = (x*10+a[i]) % b;
	}

In this way, c[i] stores the result quotient of division. For example: 4567 / 23 = 0198 ... 13.
It is found that the result of array c has 0. How to take it out? During multiplication, we use the len– method to take it out, and for division, we use len++; let the c array index move back one place so that the leading 0 is ignored.

	// 去除前导〇
	int lenc=0;
	while(c[lenc]==0 && lenc<len){
    
    
		lenc++;
	}

In the final output, the beginning of the index should start from lenc!

	for(int i=lenc;i<len;i++){
    
    
		cout<<c[i];
	}

Complete code for dividing high by low:

#include<iostream>
#include<string>
using namespace std;
string s;
int a[1000],b,c[10000],x=0;
int main(){
    
    
	cin>>s>>b;
	int len = s.size(); 
	for(int i=0;i<len;i++){
    
    
		a[i] = s[i]-'0';
	}
	for(int i=0;i<len;i++){
    
    
		c[i] = (x*10+a[i]) / b;
		x = (x*10+a[i]) % b;
	}
	int lenc=0;
	while(c[lenc]==0 && lenc<len){
    
    
		lenc++;
	}
	for(int i=lenc;i<len;i++){
    
    
		cout<<c[i];
	}
	return 0;
}

Insert image description here

Guess you like

Origin blog.csdn.net/weixin_44775255/article/details/129527957