大整數運算詳解升級版

目錄

大整數的存儲

大整數的四則運算

高精度加法

高精度減法

高精度與低精度的乘法

高精度與低精度的除法?

大整數的存儲

對于大整數使用數組存儲,例如定義int型數組d[1000],那么這個數組中的每一位就代表了存放的整數的每一位。如將整數235813存儲到數組中,則有d[0]=3,d[1]=1,d[2]=8,d[3]=5,d[4]=3,d[5]=2,即整數的高位存儲在數組的高位,整數的低位存儲在數組的低位。不反過來存儲的原因是,在進行運算的時候都是從整數低位到高位進行枚舉,順位存儲和這種思維相和。但是也會由此產生一個需要注意的問題:把整數按照字符串%s讀入的時候,實際上是逆位存儲的,即str[0]='2',str[1]='3',……,str[5]='3',因此在讀入之后需要在另存為d[]數組的時候反轉一下。

而為了方便隨時獲取大整數的長度,一般都會定義一個int型變量len來記錄其長度,并和d數組組合成結構體。

struct bign{int d[1000];int len;
};

顯然,在定義結構體變量之后,需要馬上初始化結構體,為了減少在實際輸入代碼時總是忘記初始化的問題,在結構體內部加上以下代碼:

	bign(){memset(d,0,sizeof(d));len=0;}

因此大整數結構體就變成了這樣:

struct bign{int d[1000];int len;bign(){memset(d,0,sizeof(d));len=0;}
};

這樣在每次定義結構體變量時,都會自動對該變量進行初始化。

而輸入大整數時,一般都是先用字符串讀入,然后再把字符串另存為bign結構體。由于使用char數組進行讀入時,整數的高位會變成數組的低位,而整數的低位會變成數組的高位,因此為了讓整數在bign中是順序存儲,需要讓字符串倒著賦給d[]數組。

bign change(char str[]){bign a;a.len=strlen(str);for(int i=0;i<a.len;i++){a.d[i]=str[a.len-i-1]-'0';}return 0;
}

如果要比較兩個bign變量的大小,規則也很簡單:先判斷兩者的 len大小,如果不相等,則以長的為大;如果相等,則從高位到低位進行比較,直到出現某一位不等,就可以判斷兩個數的大小。具體代碼如下:

int compare(bign a,bign b){if(a.len>b.len){return 1;//a大 }else if(a.len<b.len){return -1;//b大 }else{for(int i=a.len-1;i>=0;i--){if(a.d[i]>b.d[i]){return 1;}else if(a.d[i]<b.d[i]){return -1;}}return 0;//兩數相等 }
}

接下來主要介紹四個運算:(1)高精度加法;(2)高精度減法;(3)高精度與低精度的乘法;(4)高精度與低精度的除法。

大整數的四則運算

高精度加法

將改為上的兩個數字和進位相加,得到的結果取個位數作為該位結果,取十位數作為新的進位。

bign add(bign a,bign b){bign c;int carry=0;//進位for(int i=0;i<a.len||i<b.len;i++){int temp=a.d[i]+b.d[i]+carry;c.d[c.len++]=temp%10;carry=temp/10;} if(carry!=0){c.d[c.len++]=carry;}return 0;
}

下面是完整的A+B的代碼。

#include<stdio.h>
#include<string.h>
struct bign{int d[1000];int len;bign(){memset(d,0,sizeof(d));len=0;}
};
bign change(char str[]){bign a;a.len=strlen(str);for(int i=0;i<a.len;i++){a.d[i]=str[a.len-i-1]-'0';}return a;
}
bign add(bign a,bign b){bign c;int carry=0;for(int i=0;i<a.len||i<b.len;i++){int temp=a.d[i]+b.d[i]+carry;c.d[c.len++]=temp%10;carry=temp/10;}if(carry!=0){c.d[c.len++]=carry;}return c;
}
void print(bign a){for(int i=a.len-1;i>=0;i--){printf("%d",a.d[i]);}
}
int main(){char str1[1000],str2[1000];scanf("%s%s",str1,str2);bign a=change(str1);bign b=change(str2);print(add(a,b));return 0;
}

最后指出,這樣寫法的條件是兩個對象都是非負整數。如果有一方是負的,可以在轉換到數組這一步時去掉其負號,然后采用高精度減法;如果兩者都是負的,就都去掉負號后用高精度加法,最后把負號再加回去即可。

高精度減法

對某一步,比較被減位和減位,如果不夠減,則令被減位的高位減1, 被減位加10再進行減法;如果夠減,則直接減。最后一步要注意減法后高位可能有多余的0,要忽視它們,但也要保證結果至少有一位數。

bign sub(bign a,bign b){bign  c;for(int i=0;i<a.len||i<b.len;i++){if(a.d[i]<b.d[i]){a.d[i+1]--;a.d[i]+=10;}c.d[c.len++]=a.d[i]-b.d[i];}while(c.len-1>=1&&c.d[c.len-1]==0){c.len--;}return c;
}

高精度減法的完整代碼即為把上面的sub函數替代高精度加法中add函數的位置即可,記得 調用的時候也是用sub函數。

高精度與低精度的乘法

取bign的某位與int型整體相乘,再與進位相加,所得結果的個位數作為該位結果,高位部分作為新的進位。

bign multi(bign a,int b){bign c;int carry=0;for(int i=0;i<a.len;i++){int temp=a.d[i]*b+carry;c.d[c.len++]=temp%10;carry=temp/10;}while(carry!=0){c.d[c.len++]=carry%10;carry/=10;}return c;
}

完整的A*B的代碼只需要把高精度加法中的add函數改成這里的multi函數,并注意輸入的時候b是作為int型輸入即可。

高精度與低精度的除法?

上一步的余數乘以10加上該步的位,得到該步臨時的被除數,將其與除數比較:如果不夠除,則該位的商為0;如果夠除,則商即為對應的商,余數即為對應的余數。最后一位要注意減法后高位可能有多余的0,要忽視它們,但也要保證結果至少有一位數。

bign divide(bign a,int b,int& r){bign c;c.len=a.len;for(int i=a.len-1;i>=0;i--){r=r*10+a.d[i];if(r<b){c.d[i]=0;}else{c.d[i]=r/b;r=r%b;}}while(c.len-1>=1&&c.d[c.len-1]==0){c.len--;}return c;
}

在上述代碼中,考慮到函數每次只能返回一個數據,而很多題目里面會經常要求得到余數,因此把余數寫成引用的形式直接作為參數傳入,或是把r設成全局變量。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/16953.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/16953.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/16953.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

android requireActivity() 和 getActivity()使用問題

requireActivity() 和 getActivity() 都是從 Fragment 中獲取宿主 Activity 的方法,但它們有一些不同的行為和使用場景。 requireActivity() 拋出異常:如果 Fragment 沒有附加到任何 Activity,調用 requireActivity() 會拋出 IllegalStateException。安全性:通常在你確定 …

新品 | Forge? 1GigE IP67工業相機助力智能農業、食品和飲料行業

近日&#xff0c;51camera的合作伙伴Teledyne FLIR IIS推出Forge 1GigE IP67,它是Forge系列的最新工業相機&#xff0c;旨在在惡劣的工業環境中運行&#xff0c;同時確保高效的生產能力。Forge 1GigE IP67致力于為工廠自動化提供先進成像系統的最新產品。 Forge 1GigE IP67相機…

python-pytorch 實現seq2seq+luong general concat attention 完整代碼

接上一篇https://blog.csdn.net/m0_60688978/article/details/139046644 # def getAQ(): # ask[] # answer[] # with open("./data/flink.txt","r",encoding"utf-8") as f: # linesf.readlines() # for line in lin…

MyBatis多數據源配置與使用,基于ThreadLocal+AOP

導讀 MyBatis多數據源配置與使用其一其二1. 引依賴2. 配置文件3. 編寫測試代碼4. 自定義DynamicDataSource類5. DataSourceConfig配置類6. AOP與ThreadLocal結合7. 引入AOP依賴8. DataSourceContextHolder9. 自定義注解UseDB10. 創建切面類UseDBAspect11. 修改DynamicDataSourc…

jQuery里添加事件 (代碼)

直接上代碼 <!DOCTYPE html> <html><head></head><body><input type"text" placeholder"城市" id"city" /><input type"button" value"添加" id"btnAdd" /><ul id…

PTA 計算矩陣兩個對角線之和

計算一個nn矩陣兩個對角線之和。 輸入格式: 第一行輸入一個整數n(0<n≤10)&#xff0c;第二行至第n1行&#xff0c;每行輸入n個整數&#xff0c;每行第一個數前沒有空格&#xff0c;每行的每個數之間各有一個空格。 輸出格式: 兩條對角線元素和&#xff0c;輸出格式見樣例…

Android存儲系統成長記

用心堅持輸出易讀、有趣、有深度、高質量、體系化的技術文章 本文概要 您一定使用過Context的getFileStreamPath方法或者Environment的getExternalStoragePublicDirectory方法&#xff0c;甚至還有別的方法把數據存儲到文件中&#xff0c;這些都是存儲系統提供的服務&#x…

PTA 判斷兩個矩陣相等

Peter得到兩個n行m列矩陣&#xff0c;她想知道兩個矩陣是否相等&#xff0c;請你用“Yes”&#xff0c;“No”回答她&#xff08;兩個矩陣相等指的是兩個矩陣對應元素都相等&#xff09;。 輸入格式: 第一行輸入整數n和m&#xff0c;表示兩個矩陣的行與列&#xff0c;用空格隔…

修改元組元素

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 場景模擬&#xff1a;伊米咖啡館&#xff0c;由于麝香貓咖啡需求量較大&#xff0c;庫存不足&#xff0c;店長想把它換成拿鐵咖啡。 實例08 將麝香貓…

chrome瀏覽器驅動下載

跑自動化的時候&#xff0c;需要打開谷歌瀏覽器&#xff0c;這個時候提示瀏覽器驅動找不到咋辦呢&#xff1f; 1、網上搜索找到了這篇文章&#xff1a;https://www.cnblogs.com/laoluoits/p/17710501.html&#xff1b;按照文章介紹&#xff0c; 首先找到&#xff1a;CNPM Bin…

D - Permutation Subsequence(AtCoder Beginner Contest 352)

題目鏈接: D - Permutation Subsequence (atcoder.jp) 題目大意&#xff1a; 分析&#xff1a; 相對于是記錄一下每個數的位置 然后再長度為k的區間進行移動 然后看最大的pos和最小的pos的最小值是多少 有點類似于滑動窗口 用到了java里面的 TreeSet和Map TreeSet存的是數…

解決 Spring Boot 應用啟動失敗的問題:Unexpected end of file from server

解決 Spring Boot 應用啟動失敗的問題&#xff1a;Unexpected end of file from server 博主貓頭虎的技術世界 &#x1f31f; 歡迎來到貓頭虎的博客 — 探索技術的無限可能&#xff01; 專欄鏈接&#xff1a; &#x1f517; 精選專欄&#xff1a; 《面試題大全》 — 面試準備的…

Spring AOP失效的場景事務失效的場景

場景一&#xff1a;使用this調用被增強的方法 下面是一個類里面的一個增強方法 Service public class MyService implements CommandLineRunner {private MyService myService;public void performTask(int x) {System.out.println("Executing performTask method&quo…

爬蟲學習--15.進程與線程(2)

線程鎖 當多個線程幾乎同時修改某一個共享數據的時候&#xff0c;需要進行同步控制 某個線程要更改共享數據時&#xff0c;先將其鎖定&#xff0c;此時資源的狀態為"鎖定",其他線程不能改變&#xff0c;只到該線程釋放資源&#xff0c;將資源的狀態變成"非鎖定…

Linux如何設置共享文件夾

打開虛擬機->菜單->虛擬機設置->選項->共享文件夾->總是啟用。點擊添加按鈕->彈出添加向導->點擊瀏覽按鈕&#xff0c;從windows中選擇一個文件夾&#xff0c;確定即可。

[Windows] GIF動畫、動圖制作神器 ScreenToGif(免費)

ScreenToGif 是開源免費的 Gif 動畫錄制工具&#xff0c;小巧原生單文件&#xff0c;功能很實用。它有錄制屏幕、錄制攝像頭、錄制畫板、圖像編輯器等功能&#xff0c;可以將屏幕任何區域及操作過程錄制成 GIF 格式的動態圖像。保存前還可對 GIF 圖像編輯優化&#xff0c;支持自…

末日設計1.00

故事背景: 在不遠的未來&#xff0c;世界陷入了末日危機。資源枯竭、社會秩序崩潰&#xff0c;幸存者們為了生存&#xff0c;不得不拿起武器爭奪每一寸土地和每一口食物。在這個混亂的世界中&#xff0c;你是一名傳奇狙擊手&#xff0c;憑借超凡的射擊技巧和生存智慧&#xff0…

研二學妹面試字節,竟倒在了ThreadLocal上,這是不要應屆生還是不要女生啊?

一、寫在開頭 今天和一個之前研二的學妹聊天&#xff0c;聊及她上周面試字節的情況&#xff0c;著實感受到了Java后端現在找工作的壓力啊&#xff0c;記得在18&#xff0c;19年的時候&#xff0c;研究生計算機專業的學生&#xff0c;背背八股文找個Java開發工作毫無問題&#x…

本地圖形客戶端查看git提交歷史 使用 TortoiseGit

要在本地查看提交記錄和修改歷史&#xff0c;可以使用 TortoiseGit 和 Git-SCM。這兩個工具都提供了強大的功能來管理和查看 Git 倉庫中的提交記錄和歷史修改。 使用 TortoiseGit 查看提交記錄和修改歷史 查看提交記錄&#xff08;Log&#xff09;&#xff1a; 右鍵點擊項目文…

抖音里賣什么最賺錢?4個冷門的高利潤商品,還有誰不知道!

哈嘍~我的電商月月 做抖音小店的新手朋友&#xff0c;一定很想知道&#xff0c;在抖音里賣什么最賺錢&#xff1f; 很多人都會推薦&#xff0c;日常百貨&#xff0c;小風扇&#xff0c;女裝&#xff0c;寵物用品等等&#xff0c;這些商品確實很好做&#xff0c;你們可以試試 …