• 【大整数四则运算】


     

    定义并实现超长整数类double long,要求如下:

    64位数据长度,有符号

    支持+、-、*、/运算

    支持+=、-=、/=运算

    支持cin>>和cout<<操作

    首先,我们的运算对象是大整数并且要支持cout<<和cin>>操作,数组和链表是可选择项。在这里我们用数组。数组有int型和char型,选哪个好呢?只能选char型,因为我们的大整数是有符号位的,必须用一个char字符来存储。而int型是无法进行存储的。再明确输入的第一个运算数A,输入的第二个运算数B,四则运算后得出的结果是C。

     

    其次,我们的符号在运算的时候不能代入计算,那么我们就要用一个数组K[2]来存储它,将运算数A和B先当成正数来计算(详情见下文),最后根据情况在结果前面添加正负号,听的很迷糊?没关系,看看下面你就知道了:

    *,/ 运算时,只需考略A和B的符号,大小不必考虑:

     (1).若两运算数的符号相同(即+A,+B或者-A,-B),那么得出的结果也为正的,即+C。

     (2).若两两运算数的符号不同(即+A,-B或者-A,+B),那么得出的结果是负的,即-C。

     

    +,- 运算时,既要考虑A和B的正负号,又要考虑大小:

     若两运算数的符号同为正(即+A,+B):

       (3).加运算直接竖式相加即可。

       (4).减运算首先要考虑两数的大小,若A>=B,则直接减运算,若A<B,则进行B-A运算。

     

     若两运算数的符号同为负(即-A,-B):

       (5).加运算:(-A)+(-B)=(-C),去掉括号后运算变成(+A)+(+B)=(+C)的运算。最后将结果变成(-C)即可。

       (6).减运算就变成了一个正数减去另一个正数的情况,具体见情况(4)。

     

     若两运算数的符号同为负(即+A,-B或者-A,+B):

      (7).加运算:将正数放到前面,负数放到后面,加运算就变成了减运算,具体见情况(4)。

      (8).减运算第一种情况:(+A)-(-B)。去掉括号(-B)就变成了(+B),这就成了加运算,具体见情况(3)。

      (9).减运算第二种情况:(-A)-(+B)。去掉括号后推导出-[(+A)+(+B)]运算,具体见情况(5)。

     

    运算数全为正数时的四则运算:

    加法:从低位到高位依次进行竖式相加运算,低位的数分别为m,n,借位初始化为零;若相加的结果k(m+n)超过十,那么向前一位进(k-10)位,借位即(k-10)。将当最后一位(即最高位)算完时,若还是超过十,则不要忘了为进位分配一个存储空间。要注意:须判断出运算数A和B的长度作为循环的基础。

     

    减法:从低位到高位依次进行竖式相减运算,低位的数分别为m,n,借位初始化为零;若减的结果k(m-n)小于零,那么就必须向前面相邻的高位借一位,

    同时下一次运算时记住借位的高位要减一位。减运算也要控制好循环条件,否则当A<B, (A-B)<0时,输出的结果会出现未知0.

     

    乘法:乘法也是从低位到高位依次竖式相乘,低位m1,n1相乘,记录结果,并且左移一位,以此类推,直到计算完最后一位,再将各项结果相加。得出最后结果。

     

    除法:除法是从高位向低位依次减,减时以被除数长度为单位,从高位取出大于被除数的字符串,和被除数相减,减的次数为结果,余数从剩下的除数高位再取出几位做补位,直到大于被除数。再减,循环减到被减数大于余数加上补位,那么这个新的余数作为结果返回。

    博主的代码如下:

    点开这里!XD

     (太烂不敢露脸,,,*-*)

    这是我朋友的朋友的一篇代码,写的很好(著作权归原作者所有)。(侵删)

    /*
    大数运算 
    */
    
    #include <iostream>  
    #include <string>  
    #include <string.h>  
    #include <stdio.h>  
    using namespace std;  
    const int maxn = 1000;                   // 最大运算位数  
    int max(int a, int b)  
    {  
        return a > b ? a : b;  
      
    }  
    struct bign  
    {  
        int len, s[maxn];                  //len记录数字的位数,s存储数字s[0],s[1],s[2]。分别是个位十位百位(以此类推)  
        bign() { memset(s, 0, sizeof(s)); len = 1; }  
        bign operator=(const char * num)   //将字符串赋值给大数类型  
        {  
            len = strlen(num);  
      
            for (int i = 0; i < len; i++)  
                s[i] = num[len - i - 1] - '0';  
            int i = len - 1;  
            while (i > 0 && s[i] == 0) i--;  // 验证数字的真正大小,避免“0000010”的这样情况  
            len = i + 1;  
            return *this;  
        }  
        bign operator=(int num)           //将int类型赋值给大数类型  
        {  
            char s[maxn];  
            sprintf(s, "%d", num);  
            *this = s;  
            return *this;  
        }  
        bign operator=(const bign & b)   //大数类型的互相赋值  
        {  
            len = b.len;  
            for (int i = 0; i < len; i++)  
                s[i] = b.s[i];  
      
            return *this;  
        }  
        bign(int num) { *this = num; }   //将int转换为大数类型  
        bign(const char * num) { *this = num; }  //同上  
        string str() const               //将大数类型(副本)转换为string  
        {  
            string res = "";  
            for (int i = 0; i < len; i++)  
                res = (char)(s[i] + '0') + res;  
            if (res == "")  
                res == "0";  
            return res;  
        }  
      
        bign operator+(const bign & b) const    
        {  
            bign c;  
            c.len = 0;  
            for (int i = 0, g = 0; g || i < max(len, b.len); i++)  
            {  
                int x = g;  
                if (i < len)  
                    x += s[i];  
                if (i < b.len)  
                    x += b.s[i];  
                c.s[c.len++] = x % 10;  
                g = x / 10;  
            }  
            return c;  
      
        }  
        bign operator-(const bign & b) const  
        {  
            bign c;  
            bign temp;  
            temp = *this;  
            c.len = 0;  
            for (int i = 0; i < max(temp.len, b.len); i++)  
            {  
                int x = 0;  
                if (i < temp.len)  
                    x += temp.s[i];  
                if (i < b.len)  
                    x -= b.s[i];  
                if (x >= 0)  
                    c.s[c.len++] = x;  
                else  
                {  
                    c.s[c.len++] = x + 10;  
                    temp.s[i + 1]--;  
                }  
            }  
            int i = c.len - 1;  
            while (i > 0 && c.s[i] == 0) i--;       //确定数字的真正位数  
            c.len = i + 1;  
            return c;  
      
        }  
        bign operator*(const bign & b) const  
        {  
            bign c;  
            for (int i = 0; i < len; i++)  
            {  
      
                for (int j = 0; j < b.len; j++)  
                {  
                    c.s[i + j] += s[i] * b.s[j];  
      
                }  
            }  
            for (int i = 0; i < len + b.len - 1; i++)  
            {  
                c.s[i + 1] += c.s[i] / 10;  
                c.s[i] = c.s[i] % 10;  
            }  
            for (int i = len + b.len + 2; i > 0; i--)  
            if (c.s[i] != 0)  
            {  
                c.len = i + 1;  
                break;  
            }  
            return c;  
        }  
        //定义逻辑运算符  
        bool operator<(const bign & b) const  
        {  
      
            if (len != b.len)  
                return len < b.len;  
            for (int i = len; i > 0; i--)  
            if (s[i] != b.s[i])  
                return s[i] < b.s[i];  
        }  
        bool operator>(const bign & b) const  
        {  
            return b < *this;  
        }  
        bool operator<=(const bign & b) const  
        {  
            return !(b < *this);  
        }  
        bool operator>=(const bign & b) const  
        {  
            return !(*this < b);  
        }  
        bool operator==(const bign & b) const  
        {  
            if (*this < b)  
                return false;  
            else if (*this > b)  
                return false;  
            else  
                return true;  
        }  
        bool operator!=(const bign & b) const  
        {  
            return !(*this == b);  
        }  
        //除法(整除)  
        bign operator/(const bign & b) const  
        {  
            bign temp, result;  
            temp = *this;  
            result = 0;  
            while (temp > b)  
            {  
                temp = temp - b;  
                result = result + 1;  
      
            }  
            return result;  
        }  
        //取余数  
        bign operator%(const bign & b) const  
        {  
            bign result;  
            result = *this;  
            while (result > b)  
                result = result - b;  
            return result;  
        }  
    };  
      
    istream & operator>>(istream & in, bign & x)  
    {  
        string s;  
        in >> s;  
        x = s.c_str();  
        return in;  
    }  
    ostream & operator<<(ostream & out, const bign & x)  
    {  
        out << x.str();  
        return out;  
    }  
    int main()  
    {  
        bign a, b, c;  
        cin >> a >> b;  
        cout << a + b << endl;  
        cout << a * b << endl;  
        cout << a - b << endl;  
        cout << a / b << endl;  
        cout << a % b << endl;  
        return 0;  
    }
    朋友的朋友的代码(侵删)

    转载本博请联系作者! 如有问题请在评论区评论或者发邮件:@libras

  • 相关阅读:
    红帽RHEL7版本RHCE认证学习及考试经历
    高手总结的“恋爱法”学习Linux系统,效果更好。
    IT技术学习指导之Linux系统入门的4个阶段(纯干货带图)
    深度剖析Linux与Windows系统的区别
    浅谈学习掌握linux系统的优势
    新手要想学好Linux系统就必须做好这四件事情
    为什么高手离不了Linux系统?这就是我的理由
    总结七条助你成为Linux高手的超棒忠告
    分享记录我的Linux系统入门学习经验
    Oracle--表有LONG类型复制或导数报ORA00990
  • 原文地址:https://www.cnblogs.com/libra-yong/p/6240707.html
Copyright © 2020-2023  润新知