Loading... <div class="preview"> <div class="post-inser post box-shadow-wrap-normal"> <a href="https://www.bdmcom.cn/index.php/218.html" target="_blank" class="post_inser_a no-external-link no-underline-link"> <div class="inner-image bg" style="background-image: url(https://www.bdmcom.cn/usr/themes/handsome/assets/img/sj/4.jpg);background-size: cover;"></div> <div class="inner-content" > <p class="inser-title">C语言-高精度加法</p> <div class="inster-summary text-muted"> 高精度:通俗来说就是超过了C语言整形运算范围而采用的一种算法。我们首先来了解一下:思路:那么我们是不是可以这样把每... </div> </div> </a> <!-- .inner-content #####--> </div> <!-- .post-inser ####--> </div> ## 思路: 其实和我们的高进度加法类似,都是先把字符型转换成整形,然后对位进行运算;高精度加法是对位相加,而高进度减法是对位相减。 ## 细节: <div class="tip inlineBlock success"> 当我们用一个小的数去减一个大的数时,最后的值为负数。 </div> <div class="tip inlineBlock success"> 当我们对位相减时,可能存在相减为负数的情况,这时我们就需要向高位借1了;而高位借了一个1,高位的值就需要减掉一个1;对位相减得到一个负数最后加上10。 </div> <div class="tip inlineBlock success"> 当我们最后得到一个数组,我们遍历输出时不能把最高位直至最高位以下的值不为0区间的值进行输出(比如:1234 - 1123 = 111 ;而不是等于0111),所以我们需要把最高位直至最高位以下的值不为0区间中的0去掉。 </div> ## 代码: ```cpp #include<stdio.h> #include<string.h> #define MAX 100//预定义MAX的值为100 int main() { int str1[MAX] = {0}, str2[MAX] = {0}, str3[MAX] = {0}; char str11[MAX], str22[MAX];//声明两个字符数组 int str1_num, str2_num, i, n, j, k, flag = 0;//利用flag的值判断正负号 scanf("%s", str11);//输入第一个数 str1_num = strlen(str11); for(i = 0; i < str1_num; i++)//反向遍历赋值第一个整形数组 { str1[i] = str11[str1_num - 1 - i] - '0'; } scanf("%s", str22);//输入第二个数 str2_num = strlen(str22); for(i = 0; i < str2_num; i++)//反向遍历赋值第一个整形数组 { str2[i] = str22[str2_num - 1 - i] - '0'; } n = str1_num > str2_num ? str1_num:str2_num; if(str1_num < str2_num || (strcmp(str11, str22) < 0 && str1_num == str2_num))//当一个小的数减去一个大的数时 { flag = 1;//小减大,值为负 for (i = 0; i < n; i++) { j = str2[i] - str1[i];//对位相减 if(j < 0)//当对位相减的值为负时 { str2[i+1]--;//我们需要向高位借1 ,高位的数值就减了一个 1 str3[i] = j + 10;//对位相减的值加上 10 再赋值 } else { str3[i] = j;//当对位相减为正时,我们直接赋值 } } } else//当一个大的数减去一个小的数时 { for (i = 0; i < n; i++) { j = str1[i] - str2[i]; if(j < 0) { str1[i+1]--; str3[i] = j + 10; } else { str3[i] = j; } } } if(flag == 1)//判断是否为 小数减大数 { printf("-"); } for(k = 0; k < n; k ++) { for (i = n -1; i > 0; i--)//遍历跳出 去0法 { if(str3[i] == 0) { n--; } if(str3[i] != 0) { break; } } printf("%d", str3[n - 1 - k]);//反向遍历输出最后运算结果 } return 0; } ``` 哒哒哒,服务器开了防火墙,发送文章失败。气死我了,又重新写了一边。 ## c++版: ```cpp #include<bits/stdc++.h> using namespace std; bool cmp(vector<int>A, vector<int>B){ if(A.size() < B.size())return false; else{ for(int i = A.size()-1; i >= 0 ; i--){ if(A[i] -'0' < B[i] - '0')return false; } } return true; } vector<int> sub(vector<int>&A, vector<int>&B){ vector<int>c; int k = 0; for(int i = 0; i < A.size(); i++){ k = A[i] - k; if(i < B.size()) k -= B[i]; c.push_back((k + 10) % 10); if(k < 0)k = 1; else k = 0; } while(c.size() > 1 && c.back() == 0)c.pop_back(); return c; } int main(){ string a, b; vector<int>A, B, c; cin >> a >> b; for(int i = a.size() - 1; i >= 0; i--)A.push_back(a[i] - '0'); for(int i = b.size() - 1; i >= 0; i--)B.push_back(b[i] - '0'); if(cmp(A, B)){ c = sub(A, B); for(int i = c.size() - 1; i >= 0; i--)cout <<c[i]; }else{ cout<<"-"; c = sub(B, A); for(int i = c.size() - 1; i >= 0; i--)cout <<c[i]; } return 0; } ``` 最后修改:2022 年 03 月 14 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 2 如果文章有用,请随意打赏。