一.大數乘法
我們知道,要運算兩個數的乘法,c、c++語言裏有專門的運算符*。但是當兩個數超過一定的範圍時,用普通的運算符會產生溢出,並不能得到正確的結果。如何進行運算呢?
首先,要想保存一個大數,用正常的整形或浮點類型是不夠的。所以我們可以採用字符串的形式對大數進行保存,然後編寫算法,模擬乘法運算過程即可。
1.第一個問題:兩個數字運算結果至多用多少位的字符串保存呢?
兩個4位數相乘,最大值爲9999*9999它的位數小於10000*10000的位數9位,所以兩個數字相乘的結果至多不超過兩數位數的和
2.第二個問題:運算的過程怎麼模擬?
比如:我們可以先進行類乘和累加,把結果保存到相應的字符裏,然後進行進位
1 2 3 4
1 2 3
--------------------
3 6 9 12 //一次類乘
2 4 6 8
1 2 3 4
--------------------------
1 4 10 16 17 12 //累加
1 5 1 7 8 2 //進位
但是,這裏會出現的問題就是,如果當兩個數的位數特別大是,先進行類乘累加,由於無符號字符能保存的最大值也只有255,後進行進位處理時,有可能字符保存的值已經溢出。所以,在進行處理時要一次類乘後進行進位,然後累加。
處理完思路後,編寫代碼會變得很輕鬆。
-
void bignum(char *num1, char *num2)
-
{
-
int length1 = strlen(num1);
-
int length2 = strlen(num2);
-
int i, l;
-
char *res = (char *)malloc(sizeof(char)*(length1 + length2));
-
memset(res, 0, sizeof(char)*(length1 + length2));
-
for (i = length1 - 1; i >= 0; i--)
-
for (l = length2 - 1; l >= 0; l--)
-
{
-
res[i + l + 1] += (num1[i] - '0')*(num2[l] - '0'); 類乘完累加
-
res[i + l] += res[i + l + 1] / 10;
-
res[i + l + 1] %= 10;
-
}
-
int count = 0;
-
while (res[count] == 0)
-
{
-
count++;
-
}
-
char* ret = (char *)malloc(sizeof(char)*(length1 + length2 + 2));
-
memset(ret, 0, sizeof(char)*(length1 + length2 + 2));
-
for (l = 0, i = count; i < length1 + length2; l++, i++)
-
{
-
ret[l] = res[i] + '0';
-
}
-
printf("Ret=%s\n", ret);
-
free(res);
-
free(ret);
-
}
二:實現浮點數。
實現浮點數相乘,其實和整數差不多。只不過先得把浮點數轉化爲整數,並記錄兩個數小數點的位數和,然後再得到的整數上加上相應的小數點即可
-
void bignum_float(char *str1, char *str2)
-
{
-
int length1 = strlen(str1);
-
int length2 = strlen(str2);
-
int flnum = -1;
-
int flnum2 =-1;
-
char num1[500] = { 0 };
-
char num2[500] = { 0 };
-
int i, l;
-
for (i=0,l=0; l < length1;i++,l++)
-
{
-
if (str1[l] == '.')
-
{
-
flnum++;
-
i--;
-
continue;
-
}
-
if (flnum!=-1) flnum++;
-
num1[i] = str1[l];
-
}
-
-
for (i = 0,l = 0; l < length2; i++, l++)
-
{
-
if (str2[l] == '.')
-
{
-
flnum2++;
-
i--;
-
continue;
-
}
-
if (flnum2!=-1) flnum2++;
-
num2[i] = str2[l];
-
}
-
if (flnum!=-1) length1 -= 1;
-
if (flnum2!=-1) length2 -= 1;
-
flnum = flnum + flnum2;
-
char *res = (char *)malloc(sizeof(char)*(length1 + length2));
-
memset(res, 0, sizeof(char)*(length1 + length2));
-
for (i = length1-1; i>=0;i--)
-
for (l=length2-1; l >= 0; l--)
-
{
-
res[i+l+1]+=(num1[i] - '0')*(num2[l] - '0');
-
res[i + l] += res[i + l + 1] / 10;
-
res[i + l + 1] %= 10;
-
}
-
int count = 0;
-
while (res[count] == 0)
-
{
-
count++;
-
}
-
char* ret =(char *)malloc(sizeof(char)*(length1 + length2+2));
-
memset(ret, 0, sizeof(char)*(length1 + length2 + 2));
-
for (int n=0,l = 0,i=count; i < length1 + length2; l++, i++,n++)
-
{
-
if (n == length1 + length2 -count-flnum)
-
{
-
ret[l] = '.';
-
i--;
-
continue;
-
}
-
ret[l] = res[i] + '0';
-
}
-
-
printf("Ret=%s\n",ret);
-
free(res);
-
free(ret);
-
}
結果: