超大整數的加減乘除計算方法
目錄
問題由來及解決思路:
在任何一種程式語言中,基本型別的資料都是具有一定的範圍的。例如:在Java中長整型long佔有8個位元組,即64位。那麼當兩個數足夠大,大到無法用long來定義的時候,如何進行他們的加減乘除這種簡單的運算?
在程式語言中用於儲存超級大的資料我們首先就會想到陣列。也就是用陣列的方式進行儲存,然後對陣列中的資料進行加減乘除的操作。
例如:
思路:陣列中的每一位都相對應的加減,需要進位或借位的就使用一個變數進行記錄。
超大整數的加法運算:
以下是加法運算函式:
const int N=4;//定義陣列的長度為4 也可以更長,這個看自己計算的資料的大小
static int carry=0;//定義初始進位值
//加法函式 a,b,c是使用者呼叫此函式時傳來的陣列名
void add(int *a, int *b, int *c)
{int i;
//陣列的高位儲存的資料的低位 所以我們從i=N-1開始迴圈
for(i = N - 1; i >= 0; i--)
{c[i] = a[i] + b[i] + carry;
carry=c[i]/10000;
c[i]=c[i]%10000;
}
}
其就是在模擬平時的加法運算過程。按照低位到高位的順序對應的位相加,如果有進位就使用carry進行儲存,儲存之後當進入下一個迴圈也就是其相鄰的高位進行相加時在將carry加到高位上。
以下是得出加法結果存在於c[ ]之後的輸出函式:
void print(int *c,int k)//引數k指陣列的長度
{int i;
for (i=0;i<k;i++)
printf("%04d",c[i]);//不足四位的,前面補0輸出
printf("\n");
}
這裡一定要注意的一點就是:我們在進行加法運算的時候,陣列每一個地方儲存的數不一定是4位,例如上邊例子裡面的a[ ]陣列中,有一個地方儲存的是123,b[ ]陣列中有一個地方儲存的是456,在執行加法運算的時候這個是不影響的,但是輸出的時候我們要在它的前面補0。這也算是add函式使用時候的一個規定吧,就是說陣列的每一位上都要儲存4位數。如果不這樣子規定的話,使用者想在哪裡儲存多少就儲存多少的話就會亂掉。而且add函式中/10000和%1000也就沒有了它的道理所在(與N=4無關,N=4是規定這個陣列長度,而我們這裡說的4是指陣列中每一位上必須有4個數) 為了更好的理解這個問題,我們寫個main方法去呼叫一下這個add函式:
int main()
{//1234034523670098+213654305769786
int i,d=123,a[N]={1234,345,2367,98},b[N]={213,6543,576,9786},c[N];
//將c[]清零
for (i=0;i<N;i++)
{c[i]=0;}
//呼叫add函式
add(a,b,c);
if (carry==1)
printf("%d",carry);
//呼叫print函式
print(c,N);
}
超大整數的減法運算:
以下是減法運算函式:
const int N=4;//定義陣列的長度為4 也可以更長,這個看自己計算的資料的大小
int borrow=0;//用於儲存借位的變數
void sub(int *a, int *b, int *c)
{int i;
for(i =N- 1; i >= 0; i--)
{c[i] = a[i] - b[i] - borrow;
if(c[i] >= 0)
borrow = 0;
else // 借位
{c[i] = c[i] + 10000;
borrow = 1;}
}
}
則上面的sub函式就是模擬的下面這種減法運算的過程。讓陣列對應的每一組資料進行減法運算,然後將借位borrow記下,如果有借位,在下一次迴圈也就是它的相鄰的高位的資料進行減法運算時,將borrow減下來。就是我們平時做減法運算時候的一個過程。
以下是列印輸出函式(與加法運算時的列印輸出函式相同):
void print(int *c,int k)//引數k指陣列的長度
{int i;
for (i=0;i<k;i++)
printf("%04d",c[i]);
printf("\n");
}
我們寫一個main對其進行呼叫:
int main()
{int i,a[N]={1234,5678,3344,5566},b[N]={4321,8765,8899,7766},c[N];
for (i=0;i<N;i++)
{c[i]=0;}
sub(a,b,c);
if (borrow==0)
print(c,N);
//對於執行完sub方法後的進位進行判斷,如果borrow!=0,表示a-b<0
else
{borrow=0;
sub(b,a,c);printf("-");print(c,N);
}
}
超大整數的乘法運算:
以下是乘法運算的函式:
const int N=4;
static int carry=0;//儲存進位的變數
void mul(int *a, int b, int *c)
{ // b 為乘數且其數值較小,不屬於大整數的範圍
int i, tmp;
carry = 0;
for(i =N- 1; i >=0; i--) {
tmp = a[i] * b + carry;
c[i] = tmp % 10000;
carry = tmp / 10000;
}
}
以下是列印輸出函式:
void print(int *c,int k)
{int i;
for (i=0;i<k;i++)
printf("%04d",c[i]);
printf("\n");
}
我們寫一個main對其進行測試:
int main()
{int i,d=123,a[N]={1234,5678,3344,5566},c[N];
for (i=0;i<N;i++)
{c[i]=0;}
mul(a,d,c);
//執行完mul後,如果carry!=0表示最高位上有了進位,那麼就要先把carry列印出來再呼叫print函式
if (carry!=0)
printf("%d",carry);
print(c,N);
}
超大整數的除法運算:
以下是除法運算的函式:
const int N=4;
int remain=0;
void div(int *a, int b, int *c)
{
int i, tmp;
//除法函式與其他三種不同的是它迴圈從i=0開始,因為a[0]處儲存的是資料的高位,而除法是從高位開始算起
for(i =0; i <N; i++)
{
tmp = a[i] + remain;
c[i] = tmp / b;
remain = (tmp % b) * 10000;
}
}
以下是手動進行除法運算的過程:
由以上除法運算過程大家可以看出除法是從高位向低位進行。為了更好的理解上邊的div函式,可以對其過程進行模擬,例如使用12347851 / 4列一個豎式。由實踐可知:tmp表示每次 / 4的那個數,而沒有除盡的話,是要把這個餘數加在後面的數上面接著/4,而remain就是用於儲存餘數的變數。
輸出函式:
void print(int *c,int k)
{int i;
for (i=0;i<k;i++)
printf("%04d",c[i]);
printf("\n");
}
寫一個main函式對其進行測試:
int main()
{int i,d=123,a[N]={1234,5678,3344,5566},c[N];
for (i=0;i<N;i++)
{c[i]=0;}
div(a,d,c);
print(c,N);
}
相關文章
- JavaScript浮點數加減乘除精確計算JavaScript
- shell加減乘除運算
- 浮點數的加減乘除運算細節
- 三個數字的加減乘除模運算
- MongoDB 中的【加減乘除】運算MongoDB
- Verilog實現加減乘除運算
- 位運算實現加減乘除
- JS加減乘除位移方法封裝JS封裝
- NumPy 簡單算術:加減乘除及其他運算
- 7-2 算術入門之加減乘除
- 二進位制運算加減乘除+快速冪
- 簡單的加減乘除(遞迴)遞迴
- 79 不用加減乘除做加法
- ABAP面試問題 - 不使用加減乘除等操作比較兩個整數大小面試
- BigDecimal加減乘除運算,保留2位小數點,初始化,與0的比較Decimal
- 大數模擬 加減乘除 判斷大數是否為素數 板子
- C++筆記:輸入輸出、變數、變數加減乘除C++筆記變數
- excel日期加減計算方法 excel計算日期時間差Excel
- JS 加減乘除 尤其是減法精度問題JS
- 【oracle】日期加減計算Oracle
- java的多項式的加減乘除和賦值Java賦值
- JavaScript加減乘數運算JavaScript
- 計算機組成原理浮點數加減計算機
- 高精度四件套(加減乘除)
- 每日一練(34):不用加減乘除做加法
- 請寫一個整數計算器,支援加減乘三種運算和括號。Python版本Python
- FPGA中加減乘除運算的注意問題FPGA
- 【劍指offer】65. 不用加減乘除做加法
- [每日一題] 第六題:不用加減乘除做加法每日一題
- LeetCode 劍指 Offer 65. 不用加減乘除做加法LeetCode
- CDN閘道器超大range計算方法
- Java中計算整數中唯一數字數量的3種方法Java
- mysql查詢中時間、日期加減計算MySql
- 計算機組成原理白學了,再次回顧浮點數加減計算機
- 浮點數加減法
- Oracle計算時間函式(對時間的加減numtodsinterval、numtoyminterval)Oracle函式
- 利用Python自動生成小學生加減乘除口算考試題卷,不再為手寫算術題煩惱!Python
- 【leetcode】29. Divide Two Integers 不能使用乘除法的整數除法LeetCodeIDE