高精度與大整數

高精度與大整數

1. 高精度

1.1 加法(大數+大數)

#include <bits/stdc++.h>

using namespace std;

// 返回C = A + B
vector<int> add(vector<int> &A, vector<int> &B)  // A和B存儲的都是逆序
{
    int t = 0;  // 記錄進位狀況
    vector<int> C;  // 記錄答案
    for (int i = 0; i < A.size() || i < B.size(); ++i)
    {
        if (i < A.size() ) t += A[i];  // 若是這一位有數字
        if (i < B.size())  t += B[i];
        C.push_back(t % 10);  // 加到這一位上
        t /= 10;  // 換成下一位的數字
    }
    if (t) C.push_back(1);  // 若是有剩餘,在最高位補上一
    return C;
}

int main()
{
    string a, b;
    cin >> a >> b;
    vector<int> A, B;
    for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');  // 若是a是123,那麼放入vector的順序爲321
    for (int j = b.size() - 1; j >= 0; --j) B.push_back(b[j] - '0');
    auto C = add(A, B);
    for (int i = C.size() - 1; i >= 0; --i) cout << C[i];  // 若是答案是123,那麼答案的vector C內爲321
    return 0;
}

1.2 減法(大數-大數)

#include <bits/stdc++.h>

using namespace std;

// A >= B:true, A<B:false
bool compare(vector<int> &A, vector<int> &B)
{
    if (A.size() != B.size()) return A.size() > B.size();
    for (int i = A.size() - 1; i >= 0; --i)
        if (A[i] != B[i]) return A[i] > B[i];
    return true;
}

// C = A - B
vector <int> sub(vector<int> &A, vector<int> &B)
{
    vector <int> C;  // 用來存儲答案
    int t = 0;  // 記錄是否去高位借位
    for (int i = 0; i < A.size(); ++i)
    {
        t = A[i] - t;
        if (i < B.size() ) t -= B[i];  
        C.push_back((t + 10) % 10);
        if (t < 0) t = 1; // 復原t
        else t = 0;
    }
    while (C.size() > 1 && C.back() == 0) C.pop_back();  // 去除高位的前導0
    return C;
}

int main()
{
    string a, b;
    cin >> a >> b;
    vector <int> A, B;
    for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');  // 若是a是123,那麼放入vector的順序爲321
    for (int i = b.size() - 1; i >= 0; --i) B.push_back(b[i] - '0');
    vector<int> C;
    if (!compare(A, B))
    {
        printf("-");
        C = sub(B, A);
    }
    else C = sub (A, B);
    for (int i = C.size() - 1; i >= 0; --i)  // 若是答案是123,那麼答案的vector C內爲321
    return 0;
        cout << C[i];
    return 0;
}

1.3 乘法(大數*小數)

#include <bits/stdc++.h>

using namespace std;

// C = A * n
vector<int> mul(vector<int> &A, int n)
{
    vector<int> C;  // 存儲答案
    int t = 0;
    for (int i = 0; i < A.size() || t; ++i)
    {
        if (i < A.size()) t += A[i] * n;
        C.push_back(t % 10);  // 放入當前位的數字
        t /= 10;
    }
    return C;
}

int main()
{
    string a;
    int b;
    cin >> a >> b;
    vector<int> A;
    for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');  // 若是a是123,那麼放入vector的順序爲321
    auto C = mul(A, b);
    for (int i = C.size() - 1; i >= 0; --i)  // 若是答案是123,那麼答案的vector C內爲321
        cout << C[i];
    return 0;
}

1.4 除法(大數/小數)

#include <bits/stdc++.h>

using namespace std;

vector<int > div(vector<int> &A, int b, int &r)
{
    r = 0;  // 餘數
    vector<int> C;  // 存儲答案
    for (int i = A.size() - 1; i >= 0; --i)
    {
        r = r * 10 + A[i];  
        C.push_back(r / b);  // 放入除完的結果到答案中
        r = r % b;
    }
    reverse(C.begin(), C.end());  // C一開始存儲的時候是正序,改爲反序
    while (C.size() > 1 && C.back() == 0) C.pop_back();  // 去掉前導0
    return C;
}

int main()
{
    string a;
    int b, r;
    cin >> a >> b;
    vector<int> A;
    for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');  // 若是a是123,那麼放入vector的順序爲321
    auto C = div(A, b, r);
    for (int i = C.size() - 1; i >= 0; --i)  // 商
        cout << C[i] ;
    cout << endl << r << endl;  // 餘數
    return 0;
}

2. 大整數

#include <bits/stdc++.h>
using namespace std;
//大數
struct BigInteger
{
    static const int BASE = 100000000; //和WIDTH保持一致
    static const int WIDTH = 8;        //八位一存儲,如修改記得修改輸出中的%08d
    bool sign;                         //符號, 0表示負數
    size_t length;                     //位數
    vector<int> num;                   //反序存
                                       //構造函數
    BigInteger(long long x = 0) { *this = x; }
    BigInteger(const string &x) { *this = x; }
    BigInteger(const BigInteger &x) { *this = x; }
    //剪掉前導0,而且求一下數的位數
    void cutLeadingZero()
    {
        while (num.back() == 0 && num.size() != 1)
        {
            num.pop_back();
        }
        int tmp = num.back();  // tmp是最高位
        if (tmp == 0)  // 最高位爲0,長度爲1
        {
            length = 1;
        }  // 最高位不爲0
        else
        {
            length = (num.size() - 1) * WIDTH;
            while (tmp > 0)
            {
                length++;
                tmp /= 10;
            }
        }
    }
    //賦值運算符
    BigInteger &operator=(long long x)
    {
        num.clear();
        if (x >= 0)
        {
            sign = true;
        }
        else
        {
            sign = false;
            x = -x;
        }
        do
        {
            num.push_back(x % BASE);
            x /= BASE;
        } while (x > 0);
        cutLeadingZero();
        return *this;
    }
    BigInteger &operator=(const string &str)
    {
        num.clear();
        sign = (str[0] != '-'); //設置符號
        int x, len = (str.size() - 1 - (!sign)) / WIDTH + 1;
        for (int i = 0; i < len; i++)
        {
            int End = str.size() - i * WIDTH;
            int start = max((int)(!sign), End - WIDTH); //防止越界
            sscanf(str.substr(start, End - start).c_str(), "%d", &x);
            num.push_back(x);
        }
        cutLeadingZero();
        return *this;
    }
    BigInteger &operator=(const BigInteger &tmp)
    {
        num = tmp.num;
        sign = tmp.sign;
        length = tmp.length;
        return *this;
    }
    //絕對值
    BigInteger abs() const
    {
        BigInteger ans(*this);
        ans.sign = true;
        return ans;
    }
    //正號
    const BigInteger &operator+() const { return *this; }
    //負號
    BigInteger operator-() const
    {
        BigInteger ans(*this);
        if (ans != 0)
            ans.sign = !ans.sign;
        return ans;
    }
    // + 運算符
    BigInteger operator+(const BigInteger &b) const
    {
        if (!b.sign)
        {
            return *this - (-b);
        }
        if (!sign)
        {
            return b - (-*this);
        }
        BigInteger ans;
        ans.num.clear();
        for (int i = 0, g = 0;; i++)
        {
            if (g == 0 && i >= num.size() && i >= b.num.size())
                break;
            int x = g;
            if (i < num.size())
                x += num[i];
            if (i < b.num.size())
                x += b.num[i];
            ans.num.push_back(x % BASE);
            g = x / BASE;
        }
        ans.cutLeadingZero();
        return ans;
    }
    // - 運算符
    BigInteger operator-(const BigInteger &b) const
    {
        if (!b.sign)
        {
            return *this + (-b);
        }
        if (!sign)
        {
            return -((-*this) + b);
        }
        if (*this < b)
        {
            return -(b - *this);
        }
        BigInteger ans;
        ans.num.clear();
        for (int i = 0, g = 0;; i++)
        {
            if (g == 0 && i >= num.size() && i >= b.num.size())
                break;
            int x = g;
            g = 0;
            if (i < num.size())
                x += num[i];
            if (i < b.num.size())
                x -= b.num[i];
            if (x < 0)
            {
                x += BASE;
                g = -1;
            }
            ans.num.push_back(x);
        }
        ans.cutLeadingZero();
        return ans;
    }
    // * 運算符
    BigInteger operator*(const BigInteger &b) const
    {
        int lena = num.size(), lenb = b.num.size();
        BigInteger ans;
        for (int i = 0; i < lena + lenb; i++)
            ans.num.push_back(0);
        for (int i = 0, g = 0; i < lena; i++)
        {
            g = 0;
            for (int j = 0; j < lenb; j++)
            {
                long long x = ans.num[i + j];
                x += (long long)num[i] * (long long)b.num[j];
                ans.num[i + j] = x % BASE;
                g = x / BASE;
                ans.num[i + j + 1] += g;
            }
        }
        ans.cutLeadingZero();
        ans.sign = (ans.length == 1 && ans.num[0] == 0) || (sign == b.sign);
        return ans;
    }
    //*10^n 大數除大數中用到
    BigInteger e(size_t n) const
    {
        int tmp = n % WIDTH;
        BigInteger ans;
        ans.length = n + 1;
        n /= WIDTH;
        while (ans.num.size() <= n)
            ans.num.push_back(0);
        ans.num[n] = 1;
        while (tmp--)
            ans.num[n] *= 10;
        return ans * (*this);
    }
    // /運算符 (大數除大數)
    BigInteger operator/(const BigInteger &b) const
    {
        BigInteger aa((*this).abs());
        BigInteger bb(b.abs());
        if (aa < bb)
            return 0;
        char *str = new char[aa.length + 1];
        memset(str, 0, sizeof(char) * (aa.length + 1));
        BigInteger tmp;
        int lena = aa.length, lenb = bb.length;
        for (int i = 0; i <= lena - lenb; i++)
        {
            tmp = bb.e(lena - lenb - i);
            while (aa >= tmp)
            {
                str[i]++;
                aa = aa - tmp;
            }
            str[i] += '0';
        }
        BigInteger ans(str);
        delete[] str;
        ans.sign = (ans == 0 || sign == b.sign);
        return ans;
    }
    // %運算符
    BigInteger operator%(const BigInteger &b) const
    {
        return *this - *this / b * b;
    }
    // ++ 運算符
    BigInteger &operator++()
    {
        *this = *this + 1;
        return *this;
    }
    // -- 運算符
    BigInteger &operator--()
    {
        *this = *this - 1;
        return *this;
    }
    // += 運算符
    BigInteger &operator+=(const BigInteger &b)
    {
        *this = *this + b;
        return *this;
    }
    // -= 運算符
    BigInteger &operator-=(const BigInteger &b)
    {
        *this = *this - b;
        return *this;
    }
    // *=運算符
    BigInteger &operator*=(const BigInteger &b)
    {
        *this = *this * b;
        return *this;
    }
    // /= 運算符
    BigInteger &operator/=(const BigInteger &b)
    {
        *this = *this / b;
        return *this;
    }
    // %=運算符
    BigInteger &operator%=(const BigInteger &b)
    {
        *this = *this % b;
        return *this;
    }
    // < 運算符
    bool operator<(const BigInteger &b) const
    {
        if (sign != b.sign) //正負,負正
        {
            return !sign;
        }
        else if (!sign && !b.sign) //負負
        {
            return -b < -*this;
        }
        //正正
        if (num.size() != b.num.size())
            return num.size() < b.num.size();
        for (int i = num.size() - 1; i >= 0; i--)
            if (num[i] != b.num[i])
                return num[i] < b.num[i];
        return false;
    }
    bool operator>(const BigInteger &b) const { return b < *this; }                     // >  運算符
    bool operator<=(const BigInteger &b) const { return !(b < *this); }                 // <= 運算符
    bool operator>=(const BigInteger &b) const { return !(*this < b); }                 // >= 運算符
    bool operator!=(const BigInteger &b) const { return b < *this || *this < b; }       // != 運算符
    bool operator==(const BigInteger &b) const { return !(b < *this) && !(*this < b); } //==運算符
    // 邏輯運算符
    bool operator||(const BigInteger &b) const { return *this != 0 || b != 0; } // || 運算符
    bool operator&&(const BigInteger &b) const { return *this != 0 && b != 0; } // && 運算符
    bool operator!() { return (bool)(*this == 0); }                             // ! 運算符
    //重載<<使得能夠直接輸出大數
    friend ostream &operator<<(ostream &out, const BigInteger &x)
    {
        if (!x.sign)
            out << '-';
        out << x.num.back();
        for (int i = x.num.size() - 2; i >= 0; i--)
        {
            char buf[10];
            //如WIDTH和BASR有變化,此處要修改成%0(WIDTH)d
            sprintf(buf, "%08d", x.num[i]);
            for (int j = 0; j < strlen(buf); j++)
                out << buf[j];
        }
        return out;
    }
    //重載>>使得能夠直接輸入大數
    friend istream &operator>>(istream &in, BigInteger &x)
    {
        string str;
        in >> str;
        size_t len = str.size();
        int start = 0;
        if (str[0] == '-')
            start = 1;
        if (str[start] == '\0')
            return in;
        for (int i = start; i < len; i++)
        {
            if (str[i] < '0' || str[i] > '9')
                return in;
        }
        x.sign = !start;
        x = str.c_str();
        return in;
    }
};

struct Tag
{
    string name;
    BigInteger num;
}tag[1100];
// 可用於sort函數
bool cmp(struct Tag a, struct Tag b)
{
    return a.num > b.num;
}

int main()
{
    BigInteger n;
    cin >> n;
    cout << n.e(3) << endl;  // 返回n*(10^3)
    cout << n.abs() << endl;
    string a, b;
    cin >> a >> b;
    BigInteger c(a), d(b);
    cout << c + d << endl;
    if (c == 0) cout << "yes\n";
    return 0;
}
相關文章
相關標籤/搜索