我正在尝试为非常大的数字制作一个计算器(甚至比长的更大)并且我正在使用数组来使其工作。
到目前为止,我已经完成了加法,减法和乘法。但我真的陷入了部门的角色。
修改: 新进展。作为一个朋友提到我需要每次将结果数组与除数进行比较,这样我可以在任何时候除数大于被除数时停止进度。我设法做了一个很好的功能来每次比较它。此功能单独测试,工作正常。好。现在我开始取得真正的进步。我得到了商。现在我将尝试在数组中加入商数,以便我们可以使用更大的数字!
#define MAX_SIZE 50
#define SIZE_USE (MAX_SIZE-1)
int div(int inum_first[], int inum_second[], int div_result[], int firstlen, int secondlen)
{
int i;
int check1 = 0, check2 = 0;
int zeroC = 0;
int tmp[MAX_SIZE];
for (i = 0; i <= SIZE_USE; i++)
{
tmp[i] = 0;
}
int inum_firstCP[MAX_SIZE] = { 0 };
for (i = 0; i <= 1; i++)
{
inum_firstCP[i] = inum_first[i]; // create a copy of inum_first
}
for (i = 0; i <= SIZE_USE; i++)
{
if (inum_first[i] != 0)
check1++;
if (inum_second[i] != 0)
check2++;
}
if (secondlen > firstlen)
{
zeroC++;
goto EOI;
}
if (check2 == 0)
{
puts("\nExpected error\n");
return -1;
}
int j = 0, p = 0;
int s = 0;
int o = 1; // o is Quotient!
do
{
for (i = SIZE_USE; i >= 0; i--)
{
if (tmp[i] = inum_firstCP[i] - inum_second[i] >= 0)
{
tmp[i] = inum_firstCP[i] - inum_second[i];
}
else
{
inum_firstCP[i - 1] = inum_firstCP[i - 1] - 1;
tmp[i] = (inum_firstCP[i] + 10) - inum_second[i];
}
inum_firstCP[i] = tmp[i];
}
if (compare(inum_firstCP, inum_second, firstlen, secondlen) < 0) break;
j++;
o++;
} while (j<MAX_SIZE); // anything else will also work
EOI:
return 0;
}
int compare(int inum_firstCP[], int inum_second[], int firstlen, int secondlen)
{
int c = 0, d = 0;
int i;
firstlen = MAX_SIZE, secondlen = MAX_SIZE; // temporary. will provide a better solution ASAP
if (firstlen > secondlen)
{
return 1;
}
else if (secondlen > firstlen)
{
return -1;
}
else
{
for (i = 0; i < firstlen; i++)
{
if (inum_firstCP[i] > inum_second[i]) c++;
else if (inum_second[i] > inum_firstCP[i]) d++;
}
if (c>d) return 1;
else if (d>c) return -1;
}
return 0; // else
}
答案 0 :(得分:4)
如果您减去那些大数字,最简单的解决方案是取两个数字并从另一个数字中减去一个,直到剩下少于零的数字。这是基本的解决方案,它有效,但有点慢。
为了使速度更快你可以做到以下几点,取除数,乘以2,如果它小于被除数,继续乘以。当你达到第一个数字更大时,被除数将相应的位设置为1,减去乘以的被除数然后对结果做同样的操作。 在wiki上有很好的描述。
为了使其工作,您需要实现自己的比较功能。 假设您将在结构len中存储malloc分配的大小,您可以执行以下操作:
int compare( mynum &a, mynum &b){
if (a.len() > b.len()){
return 1;
} else (if b.len() > a.len()){
return -1;
} else(){
for(int i = b.len(); i > 0; i--){
if (a[i] > b[i]){
return 1;
} else if(b[i] > a[i]){
return -1;
}
}
#if we get there the numbers are the same
return 0;
}
}
答案 1 :(得分:1)
之前我已经完成了这项工作,非常乐意用手工完成它,并在每一步进行多次减法修改。算法是这样的:
在没有除数大于股息的情况下,尽可能多地将除数乘以十。
尽可能多地从除息中减去除数,并记住多少次。
剩下的所有减法都是新的红利。
在步骤(1)重复,直到被除数小于除数。
目前的股息是“休息”。
步骤(3)中记住的所有数字都是从左到右排序的“结果”(左计算的第一个)。
好的,我们试试吧:
E.g。你有25391,想把它除以71。
(1) 25391 and 71 * 10 = 710
25391 and 710 * 10 = 7100
25391 and 7100 * 10 = 71000 <-- TOO BIG
(2) 25391 - 7100 => X
18291 - 7100 => X
11191 - 7100 => X
4091 - 7100 <--- NOT POSSIBLE
(3) Number of X: 3
(4) 4091 > 71, okay, back to step 1.
(1) 4091 and 71 * 10 = 710
4091 and 710 * 10 = 7100 <--- TOO BIG
(2) 4091 - 710 => X
3381 - 710 => X
2671 - 710 => X
1961 - 710 => X
1251 - 710 => X
541 - 710 <--- NOT POSSIBLE
(3) Number of X: 5
(4) 541 > 71, okay, back to step 1
(1) 541 and 71 * 10 = 710 <--- TOO BIG
(2) 541 - 71 => X
470 - 71 => X
399 - 71 => X
328 - 71 => X
257 - 71 => X
186 - 71 => X
115 - 71 => X
44 - 71 <--- NOT POSSIBLE
(3) Number of X: 7
(4) 44 > 71, WRONG, continue with step 5
(5) Rest is 44
(6) Result is 357
如果您刚刚测试了从25391减去71的频率,那么这个循环将有 357次迭代!当然,我的解决方案使用乘法,但老实说,乘以10并不是真正的乘法,只是将所有数字向左移一个位置,在右上角移一个零。
算法需要尽可能多的迭代,因为结果有数字,每个数字最多需要9次迭代(带减法)。
答案 2 :(得分:0)
@Mecki用54 664 455 645 655除以5 465 126 544尝试,它失败。在第3步中,您必须添加一个数字“ 0”,该数字对应于除数(x n x 10)和“ rest”之间的长度差。也就是说,如果其余部分为13190205655(11位数字长),除数为54651265265440000(14位数字长),则在执行下一个循环之前,必须在结果中添加三个“ 0”。