zoukankan      html  css  js  c++  java
  • 大数运算之加减乘除

    大数运算

    1.为什么要有大数运算

    我们都知道计算机能够储存的各种类型数的大小是有限的,比如int型在32位的情况下范围是从-231~231-1,那么如果我们要计算的数非常的大,我们该如何做呢?那样便需要运用到大数运算。

    2.大数运算怎么实现

    大数运算本质上来说是模仿人们进行笔算时的操作,将人们笔算时的操作通过代码来实现,从而达到实现大数运行的结果。

    3.大数加法

    c++代码如下:

    #include <cstring>
    #include <cstdio>
    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("
    ");
        return 0;
    }
    

    4.大数减法

    C++代码如下:

    #include <cstring>
    #include <cstdio>
    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("
    ");
    	return 0;
    }
    

    5.大数乘法

    C++代码如下:

    #include <cstring>
    #include <cstdio>
    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("
    ");
        return 0;
    }
    

    6.大数除法

    C++代码如下:

    #include <cstdio>
    #include <cstring>
    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
    ");
            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("
    ");
        return 0;
    }
  • 相关阅读:
    【webpack 系列】进阶篇
    【webpack 系列】基础篇
    手写 Promise 符合 Promises/A+规范
    React-redux: React.js 和 Redux 架构的结合
    Redux 架构理解
    javascript 中的 this 判定
    编译原理
    vue 响应式原理
    强大的版本管理工具 Git
    js实现跨域(jsonp, iframe+window.name, iframe+window.domain, iframe+window.postMessage)
  • 原文地址:https://www.cnblogs.com/FZfangzheng/p/7700699.html
Copyright © 2011-2022 走看看