zoukankan      html  css  js  c++  java
  • [小工程]大数类

    突然发现自己从来没有写过正儿八经的大数.于是在退役之前写一把.
    希望能在用到大数时替代掉慢死的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();
    }
    
    
  • 相关阅读:
    LVM(逻辑卷管理器)部署、扩容、缩小
    部署磁盘阵列
    docker安装
    Linux基础命令
    awk补充
    awk
    shell脚本--grep与正则表达式
    文本处理工具 -wc、cut、sort、uniq的用法及参数
    Shell脚本编程原理
    重定向与管道符
  • 原文地址:https://www.cnblogs.com/qdscwyy/p/9787181.html
Copyright © 2011-2022 走看看