【发布时间】:2015-03-16 16:19:27
【问题描述】:
我正在尝试编写一个不直接使用乘法运算符来执行两个数字相乘的 C 程序,并且它应该考虑足够大的数字,这样即使通常这两个数字的相加也不能由直接加法。
当我尝试(并成功地)编写一个使用字符串执行加法的 C 程序时,我为此受到激励,我做了以下事情:
#include<stdio.h>
#define N 100000
#include<string.h>
void pushelts(char X[], int n){
int i, j;
for (j = 0; j < n; j++){
for (i = strlen(X); i >= 0; i--){
X[i + 1] = X[i];
}
X[0] = '0';
}
}
int max(int a, int b){
if (a > b){ return a; }
return b;
}
void main(){
char E[N], F[N]; int C[N]; int i, j, a, b, c, d = 0, e;
printf("Enter the first number: ");
gets_s(E);
printf("\nEnter the second number: ");
gets_s(F);
a = strlen(E); b = strlen(F); c = max(a, b);
pushelts(E, c - a); pushelts(F, c - b);
for (i = c - 1; i >= 0; i--){
e = d + E[i] + F[i] - 2*'0';
C[i] = e % 10; d = e / 10;
}
printf("\nThe answer is: ");
for (i = 0; i < c; i++){
printf("%d", C[i]);
}
getchar();
}
它可以添加任意两个带有“N”位的数字。现在,我将如何使用它来执行大数的乘法?首先,我编写了一个函数,该函数将作为字符串输入的数字乘以数字 n(即 0
a1a2...ak = a1 x 10^(k - 1) + a2 x 10^(k - 2) + ... + ak-1 x 10 + ak
所以两个数的乘法可以使用为加法设计的解和函数(*)来实现。
如果第一个数字是 x1x2.....xn,第二个数字是 y1y2....yk,那么:
x1x2...xn x y1y2...yk = (x1x2...xn) x y1 x 10^(k-1) + .....
现在函数 (*) 可以将 (x1x2...xn) 与 y1 相乘,乘以 10^(k-1) 只是在数字旁边添加 k-1 个零;最后我们将所有这些 k 项相互相加得到结果。但困难在于只知道每个数字包含多少位,以便每次在设计用于将它们加在一起的循环内执行加法。我曾考虑过做一个空数组,每次将 (x1x2..xn) 乘以 yi x 10^(i-1) 得到的结果添加到它,但就像我说过的那样,我无法精确所需的界限,我不知道每次应该在每个获得的结果前面添加多少个零,以便使用上述算法将其添加到空数组中。当我必须从 char 类型转换为 int 类型时会出现更多困难,反之亦然。也许我让这变得比它应该的更复杂;我不知道是否有更简单的方法可以做到这一点,或者是否有我不知道的工具。我是编程初学者,除了基本工具我不懂。
有没有人可以提出解决方案、想法或算法?谢谢。
【问题讨论】:
-
为什么是字符串而不是整数数组?
-
在上述情况下,我怎样才能做到这一点?我希望用户输入两个大数,我最终必须使用间接加法和乘法;我没有看到字符串是如何不必要的(至少在几个地方)。能否请您详细说明您所说的内容?
-
换句话说,除非你有充分的理由更喜欢基数 10,否则使用基数 2^16 或 2^32(或 2^64,如果你的 C 编译器提供访问 64x64 位乘法的 128 位结果)。此外,表示以 10 为底的数字的字符串浪费了它们占用的空间的 246/256 (96%)。
-
不可以使用 BigInt 包吗?
-
这是我基于 NTT 的 Schönhage-Strassen 乘法 stackoverflow.com/q/18577076/2521214 与字符串乘法示例