[C++ study notes] Analog vertical division

Recently, I wrote a topic UVa202 about division, which needs to use the idea of ​​simulating vertical division. I didn't know it before, so I spent a little time learning this method.

The so-called simulated vertical division is to simulate the vertical division method used in our primary school division. Due to the precision limitations of the computer's floating point numbers, we can use this method to find decimals of arbitrary precision.

The first case is when the divisor is a low precision floating point number. This case is relatively simple, you only need to store each bit of the dividend into an array of type int. Then use the vertical division method to calculate step by step, store the calculation results of each step in a new int array, and use an int type variable to save the quotient.

Example:

The array num[100] saves each digit of the dividend. For convenience, you can use num[0] to save the length of the dividend.

int a is the dividend, and int b is the quotient.

Suppose the input dividend: 112352; divisor: 9;

sonum[0] == 6,num[1] == 1,num[2] == 1,...,num[6] = 2;

The first division: 1/9 is not enough to divide.

The second division: Borrow one bit later, 11/9, at this time b=2, and the result 11/9 = 1 is saved in a new array.

.........

code:

#include<iostream>
using namespace std;
int main() {
	int num[256],result[256], a, b = 0, index = 0; 
	string snum;
	cin >> snum >> a;
	num[0] = snum.length();

	for (int i = 1; i <= num[0]; i++) {
		num[i] = snum[i - 1] - '0';
	}

	for (int i = 1; i <= num[0]; i++) {
		b = b * 10 + num[i];
		if (b >= a) {
			result[i] = b / a;
			b = b % a;
		}
		else {
			result[i] = 0;
		}
	}

	int flag = false;
	for (int i = 1; i <= num[0]; i++) {
		if (result[i] != 0 && flag == false) {
			flag = true;
		}
		if(flag)
			cout << result[i];
	}
	return 0;
}

The code only divides the positive integer part, and the idea of ​​the decimal part is the same.

The second case is that the high-precision dividend is divided by a high-precision divisor. In this case, the divisor also needs to be stored in an array, so it will be much more complicated. Every time you divide by the divisor, you need to compare the size relationship between the dividend and the divisor in this step. If the dividend is greater than the divisor, then subtract the divisor each time to know that the dividend is smaller than the divisor. At the same time, in high-precision division by high-precision, the dividend will be directly used to subtract the divisor, so we need an auxiliary array to fill the divisor with '0', so that the number of digits of the dividend and the number of divisors are the same.

#include<iostream>
using namespace std;

int cmp_arr(int a[],int b[]) {
	for (int i = 1; i <= b[0]; i++) {
		if (a[i] > b[i]) return 1;
		else if(a[i] < b[i])return -1;
	}
	return 0;
}

void copy_arr(int b[], int tmpb[], int dest) {
	for (int i = 1; i <= b[0]; i++) {
		tmpb[i + dest] = b[i];
	}
	tmpb[0] = b[0] + dest;
}

void sub_arr(int a[], int b[]) {
	for (int i = b[0]; i >= 1; i--) {
		if (a[i] < b[i]) {
			a[i - 1] --;
			a[i] += 10;
		}
		a[i] -= b[i];
	}
}

void print_arr(int c[]) {
	bool flag = false;
	for (int i = 1; i <= c[0]; i++) {
		if (!flag && c[i] == 0) continue;
		flag = true;
		cout << c[i];
	}
	if (!flag) cout << '0';
}

int main() {
	int a[256], b[256], c[256];
	string stra, strb;
	cin >> stra >> strb;
	a[0] = stra.length();
	b[0] = strb.length();
	for (int i = 1; i <= a[0]; i++)
		a[i] = stra[i - 1] - '0';
	for (int i = 1; i <= b[0]; i++)
		b[i] = strb[i - 1] - '0';

	memset(c, 0, sizeof(c));

	if (cmp_arr(a, b) >= 0) c[0] = a[0] - b[0] + 1;
	else c[0] = a[0] - b[0];

	int tmpb[256] = { 0 };
	for (int i = 1; i <= c[0]; i++) {
		memset(tmpb, 0, sizeof(tmpb));
		copy_arr(b, tmpb, i - 1);
		while (cmp_arr(a, tmpb) >= 1) {
			sub_arr(a, tmpb);
			c[i]++;
		}
	}

	print_arr(c);
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_65021355/article/details/130305325