减法稍微有一点复杂,因为会处理负数,而我们所用的是字符串的形式来保存数字也是为这一点。否则用整型或其它类型时,则表示处理、保存时会相当复杂。算法也是从低位开始减。先要判断减数和被减数那一个位数长,减数位数长是正常减;被减数位数长,则被减数减减数,最后还要加上负号;两数位数长度相等时,最好比那一个数字大,否则负号处理会很繁琐;处理每一项时要,如果前一位相减有借位,就先减去上一位的借位,无则不减,再去判断是否能够减开被减数,如果减不开,就要借位后再去减,同时置借位为1,否则置借位为0。

//算法也是从低位开始减。先要判断减数和被减数那一个位数长,减数位数长是正常减;被减数位数长,则被减数减减数,最后还要加上负号;

//两数位数长度相等时,最好比那一个数字大,否则负号处理会很繁琐;处理每一项时要,如果前一位相减有借位,就先减去上一位的借位,无则不减,再去判断是否能够减开被减数,
//如果减不开,就要借位后再去减,同时置借位为1,否则置借位为0
#include<iostream>
#include<cstring>//strlen是操纵c风格字符串的标准库函数,因此要有头文件#include<cstring>
using namespace std;
bool Isequal=false;
//strcmp(s1,s2),比较两个字符串是s1,s2是否相同,如果s1等于s2,则返回0,如果s1小于s2则返回负数,如果s1大于s2则返回正数
//要定义一个比较函数,比较输入的两个数的大小,但是不能完全依靠strcmp函数,因为它有些问题,比如123456,与128比会得出128大,因为它是从数组第一位开始比较的,8大于3。
//另外写一个比较函数
int compare(char* num1,char* num2)
{
int num1length=strlen(num1);
int num2length=strlen(num2);
if(num1length>num2length) //长度不等的时候,哪个长,哪个数就大
return 1;//表示num1大于num2
else if(num1length<num2length)
return -1;//表示num1小于num2
else //两者长度相等,则用strcmp来比较大小
{
if(strcmp(num1,num2)==0)
return 0;//表示两个大数是相等的
else if(strcmp(num1,num2)>0)
return 1;//num1大于num2
else
return -1;//num1小于num2
}
}
//没有考虑相减的数中存在负数的情况,只考虑了相减的两数都是正数的情况
void Minus(char* num1,char* num2,char* result,int num1length,int num2length,int resultindex)
{
int k=compare(num1,num2);
if(k==0)//两数相等
{
Isequal=true;
return;
}
if(k==1)//num1大于num2
{
int nminus=0;//保存减法的结果
int flag=0;//标志发生了借位 
while(num1length>=0&&num2length>=0)
{
if(num1[num1length]>=(num2[num2length]+flag))
{
nminus=(num1[num1length--]-'0')-(num2[num2length--]-'0')-flag;
flag=0;//注意这里必须更新flag,因为没有向前面借位,所以flag更新为0
}
if(num1[num1length]<(num2[num2length]+flag))
{
nminus=(num1[num1length--]-'0')-(num2[num2length--]-'0')+10-flag;
flag=1;
}
result[resultindex--]=nminus+'0';
}
if(num1length<0)
{
while(num2length>=0)
{
if(num2[num2length]>=flag)
{
nminus=num2[num2length--]-'0'-flag;
flag=0;
}
else
{
nminus=num2[num2length--]-'0'+10-flag;
flag=1;
}
result[resultindex--]=nminus+'0';
}
}
if(num2length<0)
{
while(num1length>=0)
{
if(num1[num1length]>=flag)
{
nminus=num1[num1length--]-'0'-flag;
flag=0;
}
else
{
nminus=num1[num1length--]-'0'-flag+10;
flag=1;
}
result[resultindex--]=nminus+'0';
}
}
}

if(k==-1)//num2大于num1,故最后的时候还要保存一个负号
{
int nminus=0;//保存减法的结果
int flag=0;//标志借位
while(num1length>=0&&num2length>=0)
{
if(num2[num2length]>=(num1[num1length]+flag))
{
nminus=(num2[num2length--]-'0')-(num1[num1length--]-'0')-flag;
flag=0;
}
if(num2[num2length]<(num1[num1length]+flag))
{
nminus=(num2[num2length--]-'0')-(num1[num1length--]-'0')+10-flag;
flag=1;//更新flag,标志发生了借位 
}
result[resultindex--]=nminus+'0';
}
if(num1length<0)
{
while(num2length>=0)
{
if(num2[num2length]>=flag)
{
nminus=num2[num2length--]-'0'-flag;
flag=0;
}
else
{
nminus=num2[num2length--]-'0'-flag+10;
flag=1;
}
result[resultindex--]=nminus+'0';
}
}
if(num2length<0)
{
while(num1length>=0)
{
if(num1[num1length]>=flag)
{
nminus=num1[num1length--]-'0'-flag;
flag=0;
}
else
{
nminus=num1[num1length--]-'0'-flag+10;
flag=1;
}
result[resultindex--]=nminus+'0';
}
}
if(result[resultindex+1]!='0')
result[resultindex]='-';//注意这个负号的位置放置也是有讲究的,不能单纯的写为result[resultindex]='-',万一最高位刚好减为0,则要把负号放在高位上
else
result[resultindex+1]='-';
}
}
void print(char*num,int nlength)
{
bool isbegining=true;
if(Isequal)
cout<<'0'<<endl;
else
{
for(int i=0;i<nlength;i++)
{
if(num[i]!='\0')
{
if(isbegining&&num[i]!='0')//因为之前预留了空位,所以位数不够nlength位,之前为0,为了符合打印习惯,从左往右找到第一个非‘0’的值
isbegining=false;
if(!isbegining)
cout<<num[i];
}
}
cout<<endl;
}
}

int main()
{
char num1[]="123";
char num2[]="1000";
int num1length=strlen(num1)-1;//数组是从0开始
int num2length=strlen(num2)-1;//数组是从0开始
int maxlength=(num1length>num2length)? num1length:num2length;
int resultlength=maxlength+10;
int resultindex=resultlength;//用于Minus函数中数组result的标号,若不用它用resultlength则print的时候会出错
char* result=new char[resultlength];
memset(result,'0',resultlength-2);//减2是因为数组是从0开始,数组最后一位放置结束符。结果数组清0,调用了memset函数,注意是赋值‘0’而不是0,否则出错
result[resultlength-1]='\0';//数组添加结束符
resultindex--;//减掉一位,因为最后一位不放任何内容,只放结束符
Minus(num1,num2,result,num1length,num2length,resultindex);
print(result,resultlength);
return 0;
}

C++实现大数的减法相关推荐

  1. 大数的减法函数--c语言

    代码展示:   http://paste.ubuntu.com/23693598/ #include<stdio.h> #include<stdlib.h> #include& ...

  2. 大数运算(3)——大数减法

    大数的减法与大数加法的方法有相似之处的,都是模拟人工运算的,从最低位开始运算,一直到最高位. 其方法是: 首先,要判断减数和被减数哪一个位数长,减数位数长是正常减:被减数位数长,则被减数减减数,最后还 ...

  3. 大数除法——超详细讲解

    大数除法,本人认为是我目前见过大数算法中最难的一个(仅仅是个人想法),它与之前的大数加法乘法减法不同,有些难理解,下面我一点一点的分析,讲解一下如何去实现大数除法. 首先,我们要知道除法中,存在四个常 ...

  4. 二进制相减,不够减, 即小数减大数

    小数减大数怎么减法,_ -- 按照大减小的做,数前面加负号(-)例如1-2=-1

  5. 一名计科生的周总结(week 2)

    先声明一下所有代码都是直接手打的 ,没有复制粘贴,有些比较难的算法我就是到网上找视频,跟着他/她敲一遍理解其中的意义所在. 一.归并排序 之前归并排序没有怎么搞懂,这一周又仔仔细细的看了一遍,总结出来 ...

  6. Java大数加法乘法减法、36进制加法

    文章目录 大数加法 大数减法 c++版本 Java版本 大数乘法 36进制加法 c++版 Java版 大数加法 1.是整数: 2.两个数无限大,long都装不下: 3.不能用BigInteger: 4 ...

  7. 大数的四则运算(加法、减法、乘法、除法)

    大数的四则运算(加法.减法.乘法.除法) 前言: 在计算机中数字表示的范围是有限制的,比如我们熟知的 int.float.double 等数据类型所能表示的范围都是有限的,如果我们要对位数达到几十位. ...

  8. Bailian3180 整数减法【大数】

    3180:整数减法 总时间限制: 1000ms 内存限制: 65536kB 描述 两个十进制非负整数M和N,计算二者的差,既M-N. M.N最多可以是长度为200位的整数. 输入 多组数据,每组数据先 ...

  9. 经典的大数的加法、减法、乘法及阶乘

    大数加法 你需要知道的事:两个长度分别为length1和length2(length2 > length1)的正整数,如果相减则可能是一个长度为length2或者length2 - 1的数,如果 ...

最新文章

  1. Anaconda3+python3.7.10+TensorFlow2.3.0+PyQt5环境搭建
  2. Java IO流之【缓冲流和文件流复制文件对比】
  3. linux字符驱动之概念介绍
  4. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第4篇] P类复杂问题
  5. “云原生全家桶“KubeSphere 如何让企业从容迈进云原生时代?
  6. 林锐 高质量c语言编程下载,新年献礼:Go语言深度入门手册
  7. webstack响应式网站导航html源码kyuan 本地静态化版
  8. 实例说明代码段(.text)、数据段(.data)、bss段、只读数据段(.rodata)、堆栈的划分依据
  9. Spring AOP 前置通知
  10. 中国恒大拟出售恒大汽车2.66%股权 配股金额约106亿港元
  11. Android使用Gson(相当于C#的Newtonsoft.Json)非常好用
  12. 状态机finite-state machine学习笔记2——按键消抖初步(1)
  13. 台式电脑主机前面耳机插孔没声音的解决方法
  14. 埃特巴什码(Atbash Cipher)
  15. LAN9252 out端口识别不到的原因排查
  16. 软件工程课程设计项目总结与项目报告
  17. 解析|拼多多爆红背后值得借鉴的思路
  18. excel去除重复项
  19. des 加密 iOS
  20. 好久不见,最近忙起来了

热门文章

  1. suse linux 10 下安装sybase15.0.3,SUSE10下安装sybase ASE15.0
  2. java代码讲解_Java基础系列-代码块详解
  3. mmap映射大于4g的文件_尴尬,win10镜像文件install.wim大于4G,如何将它装进U盘
  4. 扩展欧几里得算法_扩展欧几里得递推算法
  5. nginx防mysql注入_nginx防止sql注入
  6. curl抓取页面是乱码 php_php curl 获取网页内容 中文乱码
  7. 计算机保存文档,2010年职称计算机考试:保存文档
  8. nginx配置静态资源html,通过nginx服务器访问静态资源(示例代码)
  9. c语言getchar的不赋任何变量,C语言中getchar中的问题
  10. linux 设备树调试必须知道的几个路径