c语言任意长度小数加减法,[c++]大数运算
一、概述
C/C++中的int类型能表示的范围是-2E31-2E31–1。类型能表示的范围是0-2E32–1,即 0-。所以,int和类型变量,都不能保存超过10位的整数。有时我们需要参与运算的数,可能会远远不止10 位,例如,可能需要保留小数点后面100位(比如求π的值),那么,即便使用能表示很大数值范围的变量,但是由于变量只有64位,所以还是不可能达到精确到小数点后面100位这样的精度。变量的精度也不足以表示一个100位的整数。一般我们称这种基本数据类型无法表示的整数为大数。如何表示和存放大数呢?在c语言下,我们可以用数组存放和表示大整数,一个数组元素,存放大数中的一位。而在c++中,使用标准库的类型,使得大数问题的计算更加实用(没有最大值的限制),更加灵活(输入更加简洁方便),更加简单(可以方便的处理小数之间的运算)。
二、算法原理简单描述:
看如下大整数的加法运算:
每一位都是num1、num2和carry的和,因此,我们在输入加数和被加数的之后,可以将内容进行一次反转,这样,[i]=num1[i]+num2[i]+carry[i-1]。反转的一个重要的原因是可以方便的将向前的进位和运算变为向后的进位运算,有利于充分发挥的特点。在这里,我们可以使用头文件下的()函数方便的实现的内容反转。当运算完毕后,反转回来即可。
当加入小数点后,我们就需要考虑一些额外的问题--小数点的位置问题,笔者在此采用了如下的策略:将输入内容格式检查之后(使用了cctpe头文件),将一个数分为小数部分和整数部分,然后先运算小数部分,将得到的carry最后和整数部分一起运算,最后将两部分的和拼接在一起。
对于大数的减法问题,基本上是大数加法的一个逆运算过程,笔者不在细讲,看源代码就可以很容易的理解。
三、程序代码:
1 /*
2 大数的运算1--加法:3 利用C++ 实现任意长度正小数、整数之间的加减法4 作者:大大维5 2017/5/56 */
7 #
8 #
9 #
10 #
11 using ;12 sum(,,,);13 sub(,,,);14 ()15 {16 ,num2;17 >>num2;19 ,num12,num21,num22;20 //输入检查21 //是否是小数的标志
22 bool =false,=false;23 for(auto c:num1)24 {25 //由数字或者数字加一个.组成
26 if(!(c)||num1.empty())27 {28 if(c=='.'&&!)29 {30 =true;31 }32 else
33 {34 cout<
48 {49 cout<
55 //字符串分割{整数部分和小数部分)
56 if()//如果是小数
57 {58 int i=0;59 while(i!=num1.size()&&num1[i]!='.')60 {61 num11+=num1[i];62 ++i;63 }64 while(++i!=num1.size())65 {66 num12+=num1[i];67 }68 //用于.XXX或XXX.型输入的控制
69 if(num11.empty())70 num11+='0';71 if(num12.empty())72 num12+='0';73 }74 else//如果是整数
75 {76 num11=num1;77 num12+='0';78 }79 if()//如果是小数
80 {81 int i=0;82 while(i!=num2.size()&&num2[i]!='.')83 {84 num21+=num2[i];85 ++i;86 }87 while(++i!=num2.size())88 {89 num22+=num2[i];90 }91 //用于.XXX或XXX.型输入的控制
92 if(num21.empty())93 num21+='0';94 if(num22.empty())95 num22+='0';96 }97 else//如果是整数str
98 {99 num21=num2;100 num22+='0';101 }102
103 cout<
107
108 //加法 较长的整数部分 较长的小数部分 较短的整数部分 较短的小数部分
109 sum( , , ,)110 {111 //小数部分计算
112 if(.size()
119 for(int i=.size(); i
122 (.begin(),.end());123 (.begin(),.end());124 //小数部分进行加法计算
125 (.size(),'0');126 int carry=0;//进位
127 for(int i=0; i!=.size(); ++i)128 {129 int a=[i]-'0',b=[i]-'0';130 a=a+b+carry;131 carry=a/10;132 [i]=(a)+'0';133 }134 //反转回来
135 (.begin(),.end());136
137
138 //整数部分计算
139 if(.size()
146 (.begin(),.end());147 (.begin(),.end());148
149
150 (.size(),'0');151 for(int i=0; i!=.size(); ++i)152 {153 int a=[i]-'0',b=[i]-'0';154 a=a+b+carry;155 carry=a/10;156 [i]=(a)+'0';157 }158 for(int i=.size(); i!=.size(); ++i)159 {160 int b=[i]-'0';161 b+=carry;162 carry=b/10;163 [i]=b+'0';164 }165 if(carry)166 {167 +=(carry+'0');168 }169 //反转回来
170 (.begin(),.end());171
172
173 //合并整数部分和小数部分
174 =+'.'+;175 ;176 }177
178 //减法 被减数的整数部分 被减数的小数部分 减数的整数部分 减数的小数部分
179 sub( , , ,)180 {181 //小数部分进行减法计算
182 int =.size()-.size();183 //补0
184 if(=0)209 {210 carry=0;211 [i]=a+'0';212 }213 else
214 {215 carry=1;216 [i]=a+10+'0';217 }218 }219 //反转回来
220 (.begin(),.end());221
222
223
224 //整数部分进行减法计算225 //反转字符串
226 (.begin(),.end());227 (.begin(),.end());228 (.size(),'0');229 for(int i=0;i!=.size();++i)230 {231 int a=[i]-'0',b=[i]-'0';232 a=a-b-carry;233 if(a>=0)234 {235 carry=0;236 [i]=a+'0';237 }238 else
239 {240 carry=1;241 [i]=a+10+'0';242 }243 }244 for(int i=.size();i!=.size();++i)245 {246 int a=[i]-'0';247 a=a-carry;248 if(a>=0)249 {250 carry=0;251 [i]=a+'0';252 }253 else
254 {255 carry=1;256 [i]=a+10+'0';257 }258 }259 if(carry)//此时除数比被除数大,结果为负数
260 {261 "*";262 }263 //反转回来
264 (.begin(),.end());265
266
267 //清楚冗余0
268 ;269 =0;270 for(int i=0;[i]=='0';++i)++;271 for(int i=;i!=.size();++i)272 +=[i];273 =;274 //合并整数部分和小数部分
275 =+'.'+;276 ;277 }
View Code
四、运行结果截图:
说明1:此处有一定的容错性,可以处理(.X或X.型的数据)
说明2:(*)表示结果为负数,不再处理
说明3:对输出格式统一控制为小数类型