挑战面试编程:大整数的加、减、乘、除

一切都是有限的,哪怕是看起来无限的时间或空间都非常可能是有限的。在计算机中内置类型的加、减、乘、除都是有限的。我们来实现一个“无限”的大整数加、减、乘、除。

下面使用C++代码实现

#include <iostream>
#include <string>
using namespace std;
//大整数的加减乘除
string add_int(string, string);
string sub_int(string, string);
string mul_int(string, string);
string div_int(string, string);
string mod_int(string, string);
string divide_int(string, string, int);inline int compare(string s1, string s2)
{if (s1.size() < s2.size())return -1;else if (s1.size() > s2.size())return 1;elsereturn s1.compare(s2);
}
/*
大整数加法
本质上仅仅处理:两个正数相加,如 "123" + "234"
其他情况需转化
1. 正加负 => "123" + "-234"  = "123" - "234" 转化为减法
2. 负加正 => "-234" + "123"  = "123" - "234"
3. 负加负 => "-123" + "-234" = -("123" + "234")
*/
string add_int(string s1, string s2)
{if (s1 == "0")return s2;if (s2 == "0")return s1;if (s1[0] == '-'){if (s2[0] == '-'){return "-" + add_int(s1.erase(0, 1), s2.erase(0, 1));  //情况三}else{return sub_int(s2, s1.erase(0, 1));  //情况二}}if (s2[0] == '-'){return sub_int(s1, s2.erase(0, 1));  //情况一}//处理本质情况string::size_type i, size1, size2;size1 = s1.size();size2 = s2.size();if (size1 < size2){for (i = 0; i < size2 - size1; i++)   //在s1左边补零s1 = "0" + s1;}else{for (i = 0; i < size1 - size2; i++)   //在s2左边补零s2 = "0" + s2;}int n1, n2;n2 = 0;size1 = s1.size();size2 = s2.size();string res;for (i = size1 - 1; i != 0; i--)   //从最低位加起{n1 = (s1[i] - '0' + s2[i] - '0' + n2) % 10;  //n1代表当前位的值n2 = (s1[i] - '0' + s2[i] - '0' + n2) / 10;  //n2代表进位res = char(n1 + '0') + res;}/*上述循环不能处理第0位的原因在于i的类型是string::size_type,它是非负类型*///对于第0位单独处理n1 = (s1[0] - '0' + s2[0] - '0' + n2) % 10;n2 = (s1[0] - '0' + s2[0] - '0' + n2) / 10;res = char(n1 + '0') + res;if (n2 == 1)res = "1" + res;return res;
}
/*
大整数减法
本质上仅仅处理:两整数相减,而且是一大减一小:"1234" - "234"
其他情况需转化
1. 小正减大正 => "234" - "1234" = -("1234" - "234")
2. 正减负 => "1234" - "-234" = "1234" + "234"
3. 负减正 => "-1234" - "234" = -("1234" + "234")
4. 负减负 => "-1234" - "-234" = "234" - "1234" = -("1234" - "234")
*/
string sub_int(string s1, string s2)
{if (s2 == "0")return s1;if (s1 == "0"){if (s2[0] == '-')return s2.erase(0, 1);return "-" + s2;}if (s1[0] == '-'){if (s2[0] == '-'){return sub_int(s2.erase(0, 1), s1.erase(0, 1));   //情况四}return "-" + add_int(s1.erase(0, 1), s2);   //情况三}if (s2[0] == '-')return add_int(s1, s2.erase(0, 1));  //情况二//调整s1与s2的长度string::size_type i, size1, size2;size1 = s1.size();size2 = s2.size();if (size1 < size2){for (i = 0; i < size2 - size1; i++)   //在s1左边补零s1 = "0" + s1;}else{for (i = 0; i < size1 - size2; i++)   //在s2左边补零s2 = "0" + s2;}int t = s1.compare(s2);if (t < 0)   //s1与s2的size同样。但 s1 < s2return "-" + sub_int(s2, s1);if (t == 0)return "0";//处理本质情况:s1 > s2string res;string::size_type j;for (i = s1.size() - 1; i != 0; i--){if (s1[i] < s2[i])   //不足,需向前借一位{j = 1;while (s1[i - j] == '0'){s1[i - j] = '9';j++;}s1[i - j] -= 1;res = char(s1[i] + ':' - s2[i]) + res;}else{res = char(s1[i] - s2[i] + '0') + res;}}res = char(s1[0] - s2[0] + '0') + res;//去掉前导零res.erase(0, res.find_first_not_of('0'));return res;
}
string mul_int(string s1, string s2)
{if (s1 == "0" || s2 == "0")return "0";//sign是符号位int sign = 1;if (s1[0] == '-'){sign *= -1;s1.erase(0, 1);}if (s2[0] == '-'){sign *= -1;s2.erase(0, 1);}string::size_type size1, size2;string res, temp;size1 = s1.size();size2 = s2.size();//让s1的长度最长if (size1 < size2){temp = s1;s1 = s2;s2 = temp;size1 = s1.size();size2 = s2.size();}int i, j, n1, n2, n3, t;for (i = size2 - 1; i >= 0; i--){temp = "";n1 = n2 = n3 = 0;for (j = 0; j < size2 - 1 - i; j++) temp = "0" + temp;n3 = s2[i] - '0';for (j = size1 - 1; j >= 0; j--){t = (n3*(s1[j] - '0') + n2);n1 = t % 10;  //n1记录当前位置的值n2 = t / 10;  //n2记录进位的值temp = char(n1 + '0') + temp;}if (n2)temp = char(n2 + '0') + temp;res = add_int(res, temp);}if (sign == -1)return "-" + res;return res;
}
string divide_int(string s1, string s2, int flag)  //flag=1,返回商;flag=0,返回余数
{string quotient, residue;if (s2 == "0"){quotient = residue = "error";if (flag == 1)return quotient;elsereturn residue;}if (s1 == "0"){quotient = residue = "0";if (flag == 1)return quotient;elsereturn residue;}//sign1是商的符号,sign2是余数的符号int sign1, sign2;sign1 = sign2 = 1;if (s1[0] == '-'){sign1 *= -1;sign2 = -1;s1.erase(0, 1);}if (s2[0] == '-'){sign1 *= -1;s2.erase(0, 1);}if (compare(s1, s2) < 0){quotient = "0";residue = s1;}else if (compare(s1, s2) == 0){quotient = "1";residue = "0";}else{string temp;string::size_type size1, size2;size1 = s1.size();size2 = s2.size();int i;if (size2 > 1) temp.append(s1, 0, size2 - 1);for (i = size2 - 1; i < size1; i++){temp = temp + s1[i];//试商for (char c = '9'; c >= '0' ; c--){string t = mul_int(s2, string(1, c));string s = sub_int(temp, t);if (s == "0" || s[0] != '-'){temp = s;quotient = quotient + c;break;}}}residue = temp;}//去除前导零quotient.erase(0, quotient.find_first_not_of('0'));residue.erase(0, residue.find_first_not_of('0'));if (sign1 == -1){quotient = "-" + quotient;}if (sign2 == -1){if (residue.empty())residue = "0";elseresidue = "-" + residue;}if (flag == 1) return quotient;else return residue;
}
string div_int(string s1, string s2)
{return divide_int(s1, s2, 1);
}
string mod_int(string s1, string s2)
{return divide_int(s1, s2, 0);
}
int main(void)
{string s1, s2;char op;while (cin >> s1 >> op >> s2){switch (op){case '+':cout << add_int(s1, s2) << endl; break;case '-':cout << sub_int(s1, s2) << endl; break;case '*':cout << mul_int(s1, s2) << endl; break;case '/':cout << div_int(s1, s2) << endl; break;case '%':cout << mod_int(s1, s2) << endl; break;default:cout << "The operator is error!" << endl; break;}}return 0;
}

c语言实现大整数加法的实例

#include <stdio.h>
#include <string.h>
#define MAXLEN 1000
char a1[MAXLEN];
char a2[MAXLEN];
static int v1[MAXLEN];
static int v2[MAXLEN];
static int v3[MAXLEN];
int i, j, n, L, z;
void main(void) {scanf("%d", &n);for (j = 0; j < n; j++) {scanf("%s%s", a1, a2);L = strlen(a1);for (i = 0; i < L; i++) v1[i] = a1[L - 1 - i] - '0';  //下标越小。位数越高L = strlen(a2);for (i = 0; i < L; i++) v2[i] = a2[L - 1 - i] - '0';for (i = 0; i < MAXLEN; i++) v3[i] = v1[i] + v2[i];for (i = 0; i < MAXLEN; i++) {if (v3[i] >= 10) {v3[i + 1] += 1;v3[i] = v3[i] % 10;}}printf("Case %d:\n", j + 1);printf("%s + %s = ", a1, a2);z = 0;for (i = MAXLEN - 1; i >= 0; i--) {if (z == 0) {if (v3[i] != 0) {printf("%d", v3[i]);z = 1;}}else {printf("%d", v3[i]);}}if (z == 0) printf("0");printf("\n");}getchar();getchar();
}
//Sample Input
//3
//0 0
//1 2
//112233445566778899 998877665544332211
//
//Sample Output
//Case 1:
//0 + 0 = 0
//Case 2:
//1 + 2 = 3
//Case 3:
//112233445566778899 + 998877665544332211 = 1111111111111111110

代码下载

大整数的加、减、乘、除 C++

全部内容的文件夹

  • CCPP Blog 文件夹

挑战面试编程:大整数的加、减、乘、除相关推荐

  1. php 超大整数计算,PHP int 超大溢出整数的 加减运算函数,如果有更好的方法欢迎探讨...

    [分享]PHP int 超大溢出整数的 加减运算函数,如果有更好的方法欢迎探讨 分享一个溢出整数加减的运算函数,刚刚写的,对于溢出的整数可以用这个来进行加减运算. 遗憾的几点是: 一代码太多: 二只有 ...

  2. php中超过int真么办,PHP int 超大溢出整数的 加减运算函数,如果有更好的方法欢迎探讨...

    [分享]PHP int 超大溢出整数的 加减运算函数,如果有更好的方法欢迎探讨 分享一个溢出整数加减的运算函数,刚刚写的,对于溢出的整数可以用这个来进行加减运算. 遗憾的几点是: 一代码太多: 二只有 ...

  3. C语言 大整数运算(加、减、乘)

    题目:大整数计算 背景介绍: 大整数一般指超过十尾的十进制整数,假定不超过五十位.这类大整数在C语言系统中因超界溢出而不能直接表达或计算. 实现方法: 以字符串形式输入.输出和存放大整数,计算时可以将 ...

  4. 拼多多2018校招内推编程-大整数相乘

    编程题] 大整数相乘 时间限制:1秒 空间限制:32768K 有两个用字符串表示的非常大的大整数,算出他们的乘积,也是用字符串表示.不能用系统自带的大整数类型. 输入描述: 空格分隔的两个字符串,代表 ...

  5. 【计算机组成原理 数字逻辑 Verilog】32位加法器的实现:支持整数的加减运算

    目录 0 前言 0.1 使用环境 0.2 知识点 0.3 注意事项 1 建模:1位加法器 1.1 构建基础模型 1.1.1 一位加法器 1.1.1.1 科技黑箱:外部端口与功能 1.1.1.2 揭秘黑 ...

  6. C语言编程之分数的加减

    求1-1/2+1/3-1/4+-+1/99-1/100. 代码: #include<stdio.h> int main(){int i=1;float sum=0;while (i< ...

  7. 求一个整数的权重 c语言,Code Kata:大整数四则运算—乘法 javascript实现

    上周练习了加减法,今天练习大整数的乘法运算. 采取的方式同样为竖式计算,每一位相乘后相加. 乘法函数: 异符号相乘时结果为负数,0乘任何数都为0 需要调用加法函数 因为输入输出的为字符串,需要去除字符 ...

  8. 山东大学软件工程应用与实践——GMSSL开源库(十)——重要的大整数

    2021SC@SDUSC 文章标题 BIGNUM的结构 大整数的加减法(绝对值加减) 绝对值加减 带符号加减 大整数的乘法 经典乘法 递归和comba乘法 小结 无论是SM2.SM9等国密算法还是以R ...

  9. c语言任意两个整数相减_大整数加减运算的C语言实现

    大整数加减运算的 C 语言实现 一 . 问题提出培训老师给出一个题目:用 C 语言实现一 个大整数计算器.初步要求支持大整数的加.减运算,例如 8888888888888+1112=888888889 ...

最新文章

  1. Nginx + php
  2. 【2016年第1期】基于大数据的小麦蚜虫发生程度决策树预测分类模型
  3. PAT 1014 Waiting in Line
  4. Codeforces 1167E 尺取法
  5. 函数进阶---闭包/装饰器/迭代器/生成器---高级特性
  6. Redfish 的版本怎么看
  7. 全球及中国电子材料市场需求分析与十四五投资潜力预测报告2021年版
  8. PIC单片机开发环境的搭建总结及新上手单片机平台如何实现快速开发的几点经验分享
  9. 阅读开源引擎源代码的方式学习游戏引擎好吗?
  10. WinRAR压缩软件安装步骤
  11. Mac谷歌浏览器关闭自动更新,下载历史版本方法,解决不自动提示保存密码的问题
  12. 把两个数和告诉A,积告诉B,A说不知道是多少, B也说不知道,这时A说我知道了, B接着说我也知道了,求这两个数是什么
  13. Python爬虫QQ音乐数据采取,公开数据获取案例之一(1),腾讯Python开发面试记录
  14. JS随手记——跨页面传值
  15. java 阿拉伯语_解析Json阿拉伯语文本
  16. STM32驱动WS2812B-2020 RGB彩灯(一)
  17. elsearch mysql实时索引_MySQL和Lucene(Elasticsearch)索引对比分析
  18. outlook邮箱显示一直启动中_win10outlook邮箱怎么设置开机自动运行 - 卡饭网
  19. 4A(统一安全管控平台)解析
  20. Android 局域网扫描

热门文章

  1. linux无法找到网卡6,CentOS 6/7克隆主机网卡无法启动解决
  2. 横流式冷却塔计算风量_10T-1000T冷却塔厂家批发零售
  3. 谷歌android wear智能腕表 价格,谷歌Android Wear 2.0更新推送:仅三款智能手表可享受...
  4. python乱码怎么办_python中输出中文乱码怎么解决
  5. C语言 底层IO openclose
  6. Hadoop HIVE 条件控制函数
  7. hadoop 自定义数据类型
  8. linux awk
  9. 3.4 多个例子中的向量化
  10. d3 选择元素 api