转载来源:
http://blog.sina.com.cn/s/blog_72c80bcf0102xs1y.html
https://www.cnblogs.com/FZfangzheng/p/7700699.html
大数加法运算实现算法如下:(1)将A、B按位对齐;(2)低位开始逐位相加;(3)对结果做进位调整。
2.2大数减法
大数减法运算实现算法如下:(1)将A、B按位对齐;(2)低位开始逐位相减;(3)对结果做借位调整。
2.3大数乘法
大数乘法运算实现算法如下:(1)引入sum2、sum1中间过渡量;(2)在n的每一位上处理m;
(3)通过每一层循环,实现乘法的加法化;(4)对结果做进位调整。
2.4大数除法
大数除法运算实现算法如下:
(1)引入al来标识a的长度,bl来标识b的长度;(2)测算a和b的长度;
(3)高位开始,对位做减法,并完成借位;(4)高位开始逐位计算商;(5)整理商,产生余数。
2.5大数取模
在取模运算中用到了上面的除法运算,只需返回余数即可。
3.结论
大数运算实际上都是建立在位运算的基础上的,实际上就是对存储大数的数组里每一个数组项进行操作。将大数翻转过来存储是为了防止在计算过程中出现进位不好表示和溢出的问题。这种处理也可以看作是对字符串的处理,即把这个数组里的每一位数字转化成字符进行处理。同时如果涉及到小数,如果是加法运算,可以把小数点前后的数据分开处理;如果是乘法运算,可将其转换成整数运算之后,再转换成小数。
我们都知道计算机能够储存的各种类型数的大小是有限的,比如int型在32位的情况下范围是从-2^31~2^31-1,那么如果我们要计算的数非常的大,我们该如何做呢?那样便需要运用到大数运算。
大数运算本质上来说是模仿人们进行笔算时的操作,将人们笔算时的操作通过代码来实现,从而达到实现大数运行的结果。
c++代码如下:
#include
#include
using namespace std;
const int Max =10001;
int main(){
char a[Max],b[Max];//用来以字符串形式存放输入的数字
int aa[Max],bb[Max];//以每位数字的形式存放输入的数字
int sum[Max];//用来存放每位数字的和
int lena,lenb;
scanf("%s%s",a,b);
lena = strlen(a);//记录数字长度
lenb = strlen(b);
//将字符转化为数字
for(int i= 0 ; i < lena; i ++){
aa[i] = a[i] - 48;
}
for(int i= 0 ; i < lenb; i ++){
bb[i] = b[i] - 48;
}
int num = 0;
//当一方数字每位都计算完后结束循环
while(lena > 0 && lenb > 0){
lena -- ;
lenb -- ;
sum[num ++ ] = aa[lena] + bb[lenb];
}
//位数较多的直接加到sum数组后面
while(lena > 0){
lena --;
sum[num ++] = aa[lena] ;
}
while(lenb > 0){
lenb -- ;
sum[num ++ ] = bb[lenb];
}
//进位操作,sum[i]>10则进位
for(int i = 0 ; i < num ; i ++ ){
if(sum[i] >= 10){
sum[i+1] += 1;
sum[i] -= 10;
}
}
//判断最高位是否进位
if(sum[num] != 0){
num ++ ;
}
for(int i = num -1 ; i >= 0 ; i -- ){
printf("%d",sum[i]);
}
printf("\n");
return 0;
}
C++代码如下:
#include
#include
using namespace std;
const int Max = 10001;
char a[Max], b[Max];
int aa[Max], bb[Max];
int sum[Max];
int lena, lenb;
int flag = 0;
//若aa>bb的值则返回true
bool cmp() {
//记录变化
bool f = false;
if (lena > lenb) {
return true;
}
else if (lena == lenb){
for (int i = 0; i < lena; i++) {
if (aa[i] > bb[i])
f = true;
if (aa[i] < bb[i] && f != true)
return false;
}
return true;
}
return false;
}
int main() {
scanf("%s%s", a, b);
lena = strlen(a);
lenb = strlen(b);
for (int i = 0; i < lena; i++) {
aa[i] = a[i] - 48;
}
for (int i = 0; i < lenb; i++) {
bb[i] = b[i] - 48;
}
int num = 0;
//判断哪个数更大
if (cmp()) {
while (lena > 0 && lenb > 0) {
lena--;
lenb--;
sum[num++] = aa[lena] - bb[lenb];
}
while (lena > 0) {
lena--;
sum[num++] = aa[lena];
}
}
else {
flag = 1;
while (lena > 0 && lenb > 0) {
lena--;
lenb--;
sum[num++] = bb[lenb] - aa[lena];
}
while (lenb > 0) {
lenb--;
sum[num++] = bb[lenb];
}
}
//若相减小于零,则向前借位
for (int i = 0; i < num; i++) {
if (sum[i] < 0) {
sum[i + 1] -= 1;
sum[i] += 10;
}
}
//添加正负号
if (flag) {
for (int i = num - 1; i >= 0; i--) {
if (sum[i] != 0) {
sum[i] = -sum[i];
break;
}
}
}
bool zero = false;
for (int i = num - 1; i >= 0; i--) {
if (sum[i] != 0)
zero = true;
if(zero == true)
printf("%d", sum[i]);
}
if (zero == false) {
printf("0");
}
printf("\n");
return 0;
}
C++代码如下:
#include
#include
using namespace std;
const int Max = 10001;
int main(){
char a[Max],b[Max];
int aa[Max],bb[Max];
int sum[Max*2];
scanf("%s%s",a,b);
int lena = strlen(a);
int lenb = strlen(b);
for (int i = 0 ; i < lena; i ++ ){
aa[i] = a[i] - 48;
}
for (int i = 0 ; i < lenb; i ++ ){
bb[i] = b[i] - 48;
}
memset(sum,0,sizeof(sum));
int num;
for(int j = lenb - 1 ; j >= 0 ; j --){
//模仿乘法,第一次放在最低位,第二次放在前一位,依次类推
num = lenb - 1 - j;
for(int i = lena - 1 ; i >= 0 ; i -- ){
sum[num ++ ] += bb[j] * aa[i];
}
}
for (int i = 0 ; i < num ; i ++ ){
//若最高位大于10,则循环位数加一,直至最高位不大于10
if(sum[num - 1] >= 10){
num ++ ;
}
sum[i + 1] += sum[i] /10 ;
sum[i] = sum[i] % 10;
}
for (int i = num- 1 ; i >= 0 ; i-- ){
printf("%d",sum[i]);
}
printf("\n");
return 0;
}
C++代码如下:
#include
#include
using namespace std;
const int Max = 10001;
int Sub(int * aa , int * bb , int lena , int lenb){
//判断是否是被除数更大,是则返回-1
if (lena < lenb){
return -1;
}
else if(lena == lenb){
for(int i = lena -1 ; i >=0 ; i--){
if (aa[i] > bb[i]) break;
else if(aa[i] < bb[i]) return -1;
}
}
for(int i = 0; i < lena ; i ++){
aa[i] -= bb[i];
if(aa[i] < 0){
aa[i+1] -= 1;
aa[i] += 10;
}
}
for (int i = lena -1 ; i >= 0 ; i--){
if (aa[i]) return (i+1);
}
return 0;
}
int main(){
char a[Max],b[Max];
int aa[Max],bb[Max];
int sum[Max];
//记录最长长度,因为除法不可能比被除数大(考虑的是整数除法)
int maxlen;
scanf("%s%s",a,b);
int lena = strlen(a);
int lenb = strlen(b);
memset(aa,0,sizeof(aa));
memset(bb,0,sizeof(bb));
memset(sum,0,sizeof(sum));
//注意逆序
for(int i = lena - 1 , j = 0 ; i >= 0 ; i -- ,j ++){
aa[j] = a[i] - 48 ;
}
for(int i = lenb - 1 , j = 0 ; i >= 0 ; i -- ,j ++){
bb[j] = b[i] - 48 ;
}
//被除数小于除数,为0
if(lena < lenb){
printf("0\n");
return 0;
}
maxlen = lena;
int n = lena - lenb;
//用于将bb数组里对应最高位的数移至aa数组最高位位置
for(int i = lena - 1 ; i >= 0 ; i --){
if(i >= n){
bb[i] = bb[i-n];
}
else{
bb[i] = 0;
}
}
lenb = lena;
int t;
for (int i = 0 ; i <= n ; i ++ ){
//循环执行减法
while((t = Sub(aa,bb+i,lena,lenb-i)) >= 0){
lena = t;
sum[n - i] ++;
}
}
int i;
for( i = maxlen -1 ;i >= 0 ;i--){
if(sum[i]) break;
}
if(i >= 0){
for(;i>=0;i--){
printf("%d",sum[i]);
}
}
else{
printf("0");
}
printf("\n");
return 0;
}