大整数四则运算

Posted 天秤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大整数四则运算相关的知识,希望对你有一定的参考价值。

 

定义并实现超长整数类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;  
}
朋友的朋友的代码(侵删)

 

以上是关于大整数四则运算的主要内容,如果未能解决你的问题,请参考以下文章

大整数运算中 2 的显式幂

用c语言实现超长整数的加法运算

大整数乘法运算

大整数的存储与加减乘除四则运算

大整数四则运算

Code Kata:大整数比较大小&大整数四则运算---加减法 javascript实现