• 大整数运算


      大整数存储

        用一个字符串读取输入的大数,在转换的时候,用反转的方式存到一个int型的数组中。

        

    struct bign{
        int d[1000];
        int len;
        bigh(){
            memset(d,0,sizeof(d));
            len=0;
        }
    } 
    bign change(string str){
        bign a;
        a.len=str.size();
        for(int i=0;i<a.len;i++){
            a.d[i]=str[a.len-i-1]-'0';
        }
        return a;
    }

      大整数比较大小

        先判断两者的len大小,如果不鲜水果等,则以长的为大;如果相等,则从高位到低位进行比较,知道出现某一位不等,就可以判断两个数的大小。

        

    int compare(bign a,bign b){
        if(a.len>b.len)    return 1;//a大 
        else if(a.len<b.len) return -1;//b大 
        else{
            for(int i=a.len-1;i>=0;i--){//从高位往低位比较 
                if(a.d[i]>b.d[i])
                    return 1;// 只要有一位a大,则a大 
                else if(a.d[i]<b.d[i])
                    return -1;//只要有一为a小,则a小 
            }
            return 0;//两数相等 
        }
    }

      高精度加法

        用竖式的形式进行计算,对其中一位进行加法的步骤,将该位上的两个数字与进位相加,得到的结果取个位数作为该位的结果,取十位数作为新的进位。

        bign add(bign a,bign b){

        bign c;
        int carry=0;//carry是进位
        for(int i=0;i<a.len||i<b.len;i++){
            int temp=a.d[i]+b.d[i]+carry;//当前位的两个数与进位相加 
            c.d[c.len++]=temp%10;//取个位数作为该位结果
            carry=temp/10;
        } 
        if(carry != 0){
            c.d[c.len++]=carry;
        }
        return c;
    } 

      高精度减法

        保证a>b。否则,交换位置,减法后先输出 “-”,再输出结果‘。

        对某一步,比较被减位和减位,如果不够减,则令被减位的高位减1、被减位+10,再进行减法;如果够减,则一直减。最后一步要注意减法后高位可能有多余的0,要除去它们,但也要至少保证结果有一位数。

        

    bign sub(bign a,bign b){
        bign c;
        for(int i=0;i<a.len||i<b.len;i++){
            if(a.d[i]<b.d[i]){
                a.d[i+1]--;//向高位借1
                a.d[i]+=10;
            }
            c.d[c.len++]=a.d[i]-b.d[i];//减法结果为当前位的结果
        }
        while(c.len-1>=1&&c.d[c.len-1]==0){
            c.len--;//去除高位的0,并且保证至少还有一位数。
        }
        return c;
    }
    bign before_sub(bign a,bign b){
        bign c;
        if(compare(a,b)==-1){//a比b小的话 
            c=sub(b,a);
            printf("-");
        }else{
            c=sub(a,b);
        }
        for(int i=c.len-1;i>=0;i--){
            printf("%d",c.d[i]);
        }
    }

      高精度与低精度的乘法

        以147*35为例,把147看作一个高精度bign类型,35看为int类型。下面操作中,35始终为一个整体。

        1、7*35=245,取5作为该位的结果,高位部分24作为进位;

        2、4*35=140,加上进位24,等于164,取个位4作为该位的结果,高位16为进位;

        3、1*35=25,加上进位16,等于51,取1为该位的结果,高位5为进位。

        4、没得乘了,进位不为0,把进位5直接作为该位的结果。

        

    bign multi(bign a,int b){
        bign c;
        int carry=0;
        for(int i=0;i<a.len;i++){
            int temp=a.d[i]*b+carry;
            c.d[c.len++]=temp%10;
            carry=temp/10;
        }
        while(carry!=0){//与加法不同,乘法的进位可能不止以为,所以用循环 
            c.d[c.len++]=carry%10;
            carry/=10;
        }
        return c;
    }

      高精度与低精度的除法

        取上一步的余数*10加上该步的位,得到该步的被除数,将其与除数比较:

          如果不够除,则该位的商为0;

          如果够除,则商为对应的商,余数即为对应的余数;

        最后一步应注意,减法后 高位可能有多余的0,要除去它们,但也保证结果至少有一位。

        

    bign divide(bign a,int b,int& r){//r是上一步的余数。 
        bign c;
        c.len=a.len;//被除数的每一位和商的每一位是一一对应的,因此先令长度相等
        for(int i=a.len-1;i>=0;i--){//从高位开始 
            r=r*10+a.d[i];//当前位和上一步的余数组合 
            if(r<b)
                c.d[i]=0;//不够除。商0;
            else{//够除 
                c.d[i]=r/b;
                r=r%b;
            } 
        } 
        while(c.len-1>=1&&c.d[c.len-1]==0){
            c.len--;//去除高位的0,但保证至少有一位数存在。 
        }
        return c; 
    }
  • 相关阅读:
    「B/S端开发」如何将DevExtreme组件添加到React应用程序?
    完整UI组件库Kendo UI for Vue R3 2021
    DevExpress WPF界面控件
    DevExpress WinForm MVVM数据和属性绑定指南(Part 1)
    界面控件Telerik UI for WinForm初级教程
    ua-parser-js 实现获取浏览器信息和操作系统信息
    vue--axios 拦截器的简单介绍及使用场景
    css 插件
    去除List集合中的重复值(四种好用的方法)
    常州大学/企业微信/电费查询脚本
  • 原文地址:https://www.cnblogs.com/hxtblogs/p/7662949.html
Copyright © 2020-2023  润新知