C 언어 덧셈과 큰 숫자의 곱셈(고정밀 숫자)

큰 수의 덧셈과 곱셈(고정밀도 숫자)

머리말

C 언어에서는 숫자의 유형과 크기가 명확하게 지정되어 있지만 int 또는 long 유형이 데이터 요구 사항을 충족하지 못하는 경우가 있으므로 이러한 숫자를 계산하려면 다른 방법을 찾아야 합니다.


고정밀 숫자 추가

분석:
이때 숫자의 범위가 최대 정수 범위를 초과하는데, 이 숫자를 저장하려면 어떤 방법을 사용해야 할까요? 우리는 먼저 문자 배열의 각 요소와 함께 정수의 각 숫자를 저장할 수 있는 배열을
생각했습니다 . 이러한 방식으로 두 개의 문자열에 두 개의 숫자를 저장할 수 있습니다. 작업을 수행하기 전에 다음 사항을 명확히 해야 합니다.

1. 문자를 숫자로 변환하려면 '0'을 빼고, 숫자를 문자로 변환하려면 '0'을 더하세요. (ascll 코드는 다음과 같습니다)

2. 캐리 배려

3. 가장 높은 비트에서 판단 수행

이러한 기초를 바탕으로 코드 작성을 시도해 볼 수 있습니다!

//直接对字符数组进行操作
#include<stdio.h>
#include<string.h>
#define max 200 
int main()
{
    
    
	int i, j, m, n, k;
	//创建两个字符数组存放这两个数字 
	char a[max], b[max];
	
	//分别读取 
	scanf("%s", a);
	scanf("%s", b); 
	
	//分别计算数组的长度(位数) 
	m = strlen(a); 
	k = n = strlen(b);
	
	//取最大位数k
	if(m > k) k = m; 
	
	// 最大数字的最后一位的下一位为字符‘0’作为读取时结束标志 
	a[k + 1] = 0;
	
	//将数字整体后移,使得两个数的对应位数对齐 
	for(i = 0; i < k; i++){
    
    
		a[k-i] = a[m-i-1];
	}
	//将其前面空余位置补字符0 
	for(i = 0; i <= k - m; i++){
    
    
		a[i] = '0';
	}
	for(i = 0; i < k; i++){
    
    
		b[k - i] = b[n - i - 1];
	}
	for(i = 0; i <= k - n;i++){
    
    
		b[i] = '0';
	}
	
	j = 0;//作为两个数字对应位数的进位和,初始化为0 
	for(i = 0; i < k; i++){
    
    
		j = (a[k - i] + b[k - i] + j - 96);//96是两个字符‘0’的 ascll码的和 ,目的是将其转化为数字形式 
		a[k - i] = j % 10 + 48;//将所得数字和赋给字符数组a相应的位数 
		j = j / 10;//取进位 
	}
	a[0] = j + 48;//防止两数字之和的位数 比 最大数字的位数还大 
	if(a[0] == '0'){
    
    
		printf("%s\n", a + 1);//没有进位的话,就从数组的第二个元素开始输出 
	}else{
    
    
		printf("%s\n", a);
	}
}

고정밀 숫자의 곱셈

또한 다음 사항에 주의해야 합니다.

1. 문자를 숫자로 변환하려면 '0'을 빼고, 숫자를 문자로 변환하려면 '0'을 더하세요. (ascll 코드는 다음과 같습니다)

2. 캐리 배려

3. 가장 높은 비트에서 판단 수행

그런데 이때 답을 저장하기 위해서는 세 번째 배열이 필요합니다. 초등학교 때 배운 수직 곱셈 공식을 아직도 기억하고 계시는지 궁금합니다만, 여기서는 약간의 변화가 있을 것입니다(여기에서는 캐리 연산을 처리하지 않습니다 ) .

             3   2   1
*            4   5   6
*--------------------------
             4   5   6
        8   10  12
   12  15   18   
*--------------------------
   12  23   32  17   6
   **所得乘积数字的位数最大只能是两个数字的位数和**

주의 깊게 관찰하면 다음과 같은 사실이 드러납니다.

	c[0]=a[0]+b[0];
	c[1]=a[0]*b[1]+a[1]*b[0];
然后我们就可以得到一个规律:
	c[i+j]+=a[i]*b[j];
#include<stdio.h>
#include<string.h>
#define max 1500
int main() {
    
    
    char c1[max], c2[max];
    scanf("%s%s", c1, c2);
    int n = strlen(c1), m = strlen(c2);
    int a[n], b[m];
    int i, j;
    //将得到的字符串转化为数字 
    for (i = 0, j = n - 1; i < n; i++, j--) {
    
    
        a[i] = c1[j] - '0';
    }
    for (i = 0, j = m - 1; i < m; i++, j--) {
    
    
        b[i] = c2[j] - '0';
    }
    
    int c[max + max];
    for (i = 0; i < max + max; i++) {
    
    
        c[i] = 0;
    }
    //将相乘的结果存放在c中 
    for (i = 0; i < n; i++) {
    
    
        for (j = 0; j < m; j++) {
    
    
            c[i + j] += a[i] * b[j];
        }
    }   
    //进行进位操作 
    for (i = 0; i < n + m; i++) {
    
    
        if (c[i] >= 10) {
    
    
            c[i + 1] += c[i] / 10;
            c[i] %= 10;
        }
    }
    //将多余位数的0跳过 ,开始输出。 
    for (j = max + max - 1; j > 0; j--) {
    
    
        if (c[j] != 0){
    
    
        	break;
		}    
    }
    for (i = j; i >= 0; i--) {
    
    
    	printf("%d", c[i]);
    }
    return 0;
}

추천

출처blog.csdn.net/The_onion/article/details/121576859