[小工程]大数类

突然发现自己从来没有写过正儿八经的大数.于是在退役之前写一把.
希望能在用到大数时替代掉慢死的Python.

项目地址Github.com/Frankaiyou/LargeIntegar
话说我在Github上写了好几个东西都没怎么有人star.
看来还是太菜了.

写的很差, Bug很多.

Module

  • Input
    • Basically completed
  • Output
    • Basically completed
  • Constructor
    • Basically completed
  • Memory management
    • Incomplete
  • Convert with other formats
    • Basically completed
  • Arithmetic operators
    • Division and Multiplicaion;
  • Relational operators
    • Basically completed
  • Logical operators
    • Basically completed
  • Subscript operators
    • Not needed for now

ToDoList

  • [ ] division;
  • [ ] Multiplicaion;
  • [ ] Fix the Compare;
  • [ ] Possible memory leaks;
  • [ ] Sub or Add is lengthy.

1.0.1

  • Fixed the Output that appear Prefix zero;
    Now it will remove the Prefix zero In The Substruction;
  • Modified the way input a LargeIntegar,
    which input a string and convert it to LargeIntegar;
  • Calculate the memory more reasonable in substruction and addition;
  • Added the new file histort.cpp, code that discarded place it here;
  • Added relational operators;
  • Streamline the Add and Sub;

1.0.1.1

  • Streamline the Add and Sub;
    But it still very lengthy;

1.0.1.2

  • Solve a Bug in convert_string_to_largeIntegar;

1.0.1.3

  • Added relational operators: (No tested!)
    '<', '>', '>=', '<=', '==', '!=' .

实现思路是用一段连续的int32来表示整段数字, 每个int32只用4位, 为的是方便乘法操作.
同时可以在一定程度上减少计算量(是一般方法的四分之一), 虽然编程难度变大很多.

日程

10-15

精简了部分代码

P1601 A+B Problem(高精)
OpenJudge 3736 大整数减法

#include <algorithm>
#include <iostream>
#include <string.h>
#include <sstream>
#include <istream>
#include <stdio.h>
#include <string>
using namespace std;

#define InitSize 30
#define MaxOfFBit 9999
#define CalcBit(X) (X > 999 ? 4 : (X > 99 ? 3 : (X > 9 ? 2 : (X > 0 ? 1 : 0))))

class LargeIntegar {
    int *Nums, *BegPos, *EndPos, size, bit; bool Sign;
public:
    LargeIntegar(int sz = InitSize) {
        Sign = false, BegPos = NULL, bit = 0;
        Nums = new int[sz], size = sz, EndPos = Nums + sz;
        std:: fill(Nums, Nums + sz, false);	
    }
    template <typename Int> 
    LargeIntegar Convert_Int_to_LargeIntegar(Int integar) {
        string Str = to_string(integar);
        return Convert_String_to_LargeIntegar(Str);
    }
    void Redistribute_Memory(int sz) {
        int* NewInt = new int[sz]; EndPos = NewInt + sz;
        std:: fill(NewInt, NewInt + sz, false);
        memcpy(Nums, NewInt + sz - size, size * sizeof(int));
        delete Nums; Nums = NewInt, size = sz; 
    }
    static LargeIntegar Convert_String_to_LargeIntegar(string& Str) {
        int sz = max(int(Str.size() + 5), InitSize);
        LargeIntegar Res = LargeIntegar(sz);
        int *p = Res.EndPos - 1;
        while (Str[0] == '0' and Str.size() > 1) Str.erase(0, 1);
        for (int i = Str.size() - 1; i >= 0; i -= 4) {
            Res.BegPos = p;
            if (i < 3) {
                *p = Str[i] - '0', Res.bit += 1;
                if (i > 0) *p += 10 * (Str[i - 1] - '0'), Res.bit += 1;
                if (i > 1) *p += 100 * (Str[i - 2] - '0'), Res.bit += 1;
                break;
            }
            *p = Str[i] - '0' + 10 * (Str[i - 1] - '0') + 
             	(Str[i - 2] - '0') * 100 + 1000 * (Str[i - 3] - '0');
            p -= 1, Res.bit += 4;
        }
        return Res;
    }
    template <typename Int>
    LargeIntegar operator = (const Int& o) {
    	return *this = Convert_Int_to_LargeIntegar(o);
    }
    friend istream& operator >> (istream &in, LargeIntegar &Int) {
        string str; in >> str;
        Int = Convert_String_to_LargeIntegar(str);
        return in;
    }
    friend ostream& operator << (ostream &out, LargeIntegar &lInt) {
        if (not lInt.BegPos) {
            out << 0; return out;
        }
        int* num = lInt.BegPos;
        if (lInt.Sign) cout << '-';
        out << *num; num += 1;
        int tmp;
        while (num != lInt.EndPos) {	
            if (*num == 0) out << "000";
            else if ((tmp = CalcBit(*num)) < 4) {
                tmp = 4 - tmp;
                while (tmp --) putchar('0');
            }
            out << *num;
            num += 1;
        }
        return out;
    }
    int operator ! () const {
    	return not(*BegPos);
    }
    bool operator < (const LargeIntegar& o) const {
        if (not Sign and o.Sign) return false;
        if (Sign and not o.Sign) return true;
        if (Sign and o.Sign) return not((-(*this)) < (-o));
        if (bit != o.bit) return bit < o.bit;
        int *p = this->BegPos, *q = o.BegPos;
        while (p != this->EndPos and q != o.EndPos) {
            if (*p != *q) return *p < *q;
            p = p + 1, q = q + 1;
        }
        return false;
    }
    bool operator >= (const LargeIntegar& o) const {
    	return not (*this < o);
    }
    bool operator == (const LargeIntegar& o) const {
    	if (not Sign and o.Sign) return false;
        if (Sign and not o.Sign) return false;
        if (Sign and o.Sign) return false;
        if (bit != o.bit) return false;
        int *p = this->BegPos, *q = o.BegPos;
        while (p != this->EndPos and q != o.EndPos) {
            if (*p != *q) return false;
            p = p + 1, q = q + 1;
        }
        return true;
    }
    bool operator != (const LargeIntegar& o) const {
    	return not (*this == o);
    }
    bool operator > (const LargeIntegar& o) const {
    	return (*this >= o and not (*this == o));
    }
    bool operator <= (const LargeIntegar& o) const {
    	return not (*this > o);
    }
    LargeIntegar operator + (const LargeIntegar& o) const {
        bool flag = false;
        if (o.Sign and Sign) flag = true;
        else if (o.Sign) return *this - (-o);
        else if (Sign) return o - (-(*this));
        if (*this < o) return o + *this;
        LargeIntegar Res = LargeIntegar(max(max(bit, o.bit) + 5, InitSize));
        int *p = EndPos - 1, *q = o.EndPos - 1, *r = Res.EndPos - 1;
        while (p != BegPos - 1) {
            *r += *p + (q == o.BegPos - 1 ? 0 : *q);
            if (*r > MaxOfFBit) {
                *(r - 1) += 1, *r %= MaxOfFBit + 1, 
                Res.BegPos = r - 1, Res.bit += 4;
            }
            else Res.BegPos = r, Res.bit += (p == BegPos ? CalcBit(*r) : 4);
            p -= 1, q -= (q == o.BegPos - 1 ? 0 : 1), r -= 1;
        }
        if (flag) Res.Sign = true;
        return Res;
    }
    LargeIntegar operator - () const {
        LargeIntegar Res = *this;
        Res.Sign ^= 1;
        return Res;
    }
    LargeIntegar operator - (const LargeIntegar& o) const {
        if (not Sign and o.Sign) return *this + (-o);
        if (Sign and not o.Sign) return -((-(*this) + o));
        if (Sign and Sign) return ((-o) - (-(*this)));
        if (*this < o) return -(o - *this);
        LargeIntegar Res = LargeIntegar(max(max(bit, o.bit) + 5, InitSize));
        int *p = EndPos - 1, *q = o.EndPos - 1, *r = Res.EndPos - 1;
        while (p != BegPos - 1) {
            *r += *p - (q == o.BegPos - 1 ? 0 : *q);
            if (*r < 0) *(r - 1) -= 1, *r += MaxOfFBit + 1, Res.BegPos = r - 1;
            else Res.BegPos = r;
            Res.bit += (p == BegPos ? CalcBit(*r) : 4);
            p -= 1, q -= (q == o.BegPos - 1 ? 0 : 1), r -= 1;
        }
        while (*Res.BegPos == 0 and Res.BegPos < Res.EndPos - 1) 
            Res.BegPos += 1;
        return Res;
    }
};

int Test() {
    LargeIntegar o, b;
    cin >> o >> b;
	cout << o << endl;
	cout << b << endl;
	printf("If A > B ? %d
", o > b);
    // o = o + b;
    // long long a = 123456789123456789ll;
    cout << (o == b) << endl;
    return 0;
}

int main () {
    return Test();
}

原文地址:https://www.cnblogs.com/qdscwyy/p/9787181.html