在 C++ 中保持超过 50 位数字

如何解决在 C++ 中保持超过 50 位数字

请告诉我如何在 C++ 中存储 50 多个数字。 你可能会说这个问题被问到并使用了字符串。但我希望对这些存储的数据执行“加”、“减”和“或”操作。

解决方法

标准库中没有 bigint 实现。 50 位小数将需要 166 位。最大的原始类型是 std::uint64_t。即使你有一个 128 位的扩展,它也不会给你带来好处,因为你仍然有点短。

如果您需要精确到如此大的数字,您必须滚动自己的 bigint 类型或搜索支持它的库(boost 可能有一个)。

如果您不需要绝对精度并且可以按位或,您可以使用浮点类型之一,例如double

,

正如位掩码已经回答的那样,到目前为止,C++ 中的 std 中没有 bigint。但是我们可以自己实现一个Bigint结构,虽然会增加操作的复杂度。

/*
  ######################################################################
  #######################   THE   BIG   INT   ##########################
*/

const int base = 1000000000;
const int base_digits = 9;

struct Int
{

    vector<int> a;
    int sign;

    /*<arpa>*/

    int size()
    {
        if (a.empty())
            return 0;
        int ans = (a.size() - 1) * base_digits;
        int ca = a.back();
        while (ca)
            ans++,ca /= 10;
        return ans;
    }

    Int operator^(const Int &v)
    {
        Int ans = 1,a = *this,b = v;
        while (!b.isZero())
        {
            if (b % 2)
                ans *= a;
            a *= a,b /= 2;
        }
        return ans;
    }

    string to_string()
    {
        stringstream ss;
        ss << *this;
        string s;
        ss >> s;
        return s;
    }

    int sumof()
    {
        string s = to_string();
        int ans = 0;
        for (auto c : s)
            ans += c - '0';
        return ans;
    }

    /*</arpa>*/

    Int() : sign(1)
    {
    }

    Int(long long v)
    {
        *this = v;
    }

    Int(const string &s)
    {
        read(s);
    }

    void operator=(const Int &v)
    {
        sign = v.sign;
        a = v.a;
    }

    void operator=(long long v)
    {
        sign = 1;
        a.clear();
        if (v < 0)
            sign = -1,v = -v;
        for (; v > 0; v = v / base)
            a.push_back(v % base);
    }

    Int operator+(const Int &v) const
    {
        if (sign == v.sign)
        {
            Int res = v;
            for (int i = 0,carry = 0; i < (int)max(a.size(),v.a.size()) || carry; ++i)
            {
                if (i == (int)res.a.size())
                    res.a.push_back(0);
                res.a[i] += carry + (i < (int)a.size() ? a[i] : 0);
                carry = res.a[i] >= base;
                if (carry)
                    res.a[i] -= base;
            }
            return res;
        }
        return *this - (-v);
    }

    Int operator-(const Int &v) const
    {
        if (sign == v.sign)
        {
            if (abs() >= v.abs())
            {
                Int res = *this;
                for (int i = 0,carry = 0; i < (int)v.a.size() || carry; ++i)
                {
                    res.a[i] -= carry + (i < (int)v.a.size() ? v.a[i] : 0);
                    carry = res.a[i] < 0;
                    if (carry)
                        res.a[i] += base;
                }
                res.trim();
                return res;
            }
            return -(v - *this);
        }
        return *this + (-v);
    }

    void operator*=(int v)
    {
        if (v < 0)
            sign = -sign,v = -v;
        for (int i = 0,carry = 0; i < (int)a.size() || carry; ++i)
        {
            if (i == (int)a.size())
                a.push_back(0);
            long long cur = a[i] * (long long)v + carry;
            carry = (int)(cur / base);
            a[i] = (int)(cur % base);
            //asm("divl %%ecx" : "=a"(carry),"=d"(a[i]) : "A"(cur),"c"(base));
        }
        trim();
    }

    Int operator*(int v) const
    {
        Int res = *this;
        res *= v;
        return res;
    }

    void operator*=(long long v)
    {
        if (v < 0)
            sign = -sign,"c"(base));
        }
        trim();
    }

    Int operator*(long long v) const
    {
        Int res = *this;
        res *= v;
        return res;
    }

    friend pair<Int,Int> divmod(const Int &a1,const Int &b1)
    {
        int norm = base / (b1.a.back() + 1);
        Int a = a1.abs() * norm;
        Int b = b1.abs() * norm;
        Int q,r;
        q.a.resize(a.a.size());

        for (int i = a.a.size() - 1; i >= 0; i--)
        {
            r *= base;
            r += a.a[i];
            int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
            int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
            int d = ((long long)base * s1 + s2) / b.a.back();
            r -= b * d;
            while (r < 0)
                r += b,--d;
            q.a[i] = d;
        }

        q.sign = a1.sign * b1.sign;
        r.sign = a1.sign;
        q.trim();
        r.trim();
        return make_pair(q,r / norm);
    }

    Int operator/(const Int &v) const
    {
        return divmod(*this,v).first;
    }

    Int operator%(const Int &v) const
    {
        return divmod(*this,v).second;
    }

    void operator/=(int v)
    {
        if (v < 0)
            sign = -sign,v = -v;
        for (int i = (int)a.size() - 1,rem = 0; i >= 0; --i)
        {
            long long cur = a[i] + rem * (long long)base;
            a[i] = (int)(cur / v);
            rem = (int)(cur % v);
        }
        trim();
    }

    Int operator/(int v) const
    {
        Int res = *this;
        res /= v;
        return res;
    }

    int operator%(int v) const
    {
        if (v < 0)
            v = -v;
        int m = 0;
        for (int i = a.size() - 1; i >= 0; --i)
            m = (a[i] + m * (long long)base) % v;
        return m * sign;
    }

    void operator+=(const Int &v)
    {
        *this = *this + v;
    }

    void operator-=(const Int &v)
    {
        *this = *this - v;
    }

    void operator*=(const Int &v)
    {
        *this = *this * v;
    }

    void operator/=(const Int &v)
    {
        *this = *this / v;
    }

    Int operator++()
    {
        *this += 1;
        return *this;
    }

    Int operator++(int)
    {
        Int temp = *this;
        *this += 1;
        return temp;
    }

    Int operator--()
    {
        *this -= 1;
        return *this;
    }

    Int operator--(int)
    {
        Int temp = *this;
        *this -= 1;
        return temp;
    }

    bool operator<(const Int &v) const
    {
        if (sign != v.sign)
            return sign < v.sign;
        if (a.size() != v.a.size())
            return a.size() * sign < v.a.size() * v.sign;
        for (int i = a.size() - 1; i >= 0; i--)
            if (a[i] != v.a[i])
                return a[i] * sign < v.a[i] * sign;
        return false;
    }

    bool operator>(const Int &v) const
    {
        return v < *this;
    }

    bool operator<=(const Int &v) const
    {
        return !(v < *this);
    }

    bool operator>=(const Int &v) const
    {
        return !(*this < v);
    }

    bool operator==(const Int &v) const
    {
        return !(*this < v) && !(v < *this);
    }

    bool operator!=(const Int &v) const
    {
        return *this < v || v < *this;
    }

    void trim()
    {
        while (!a.empty() && !a.back())
            a.pop_back();
        if (a.empty())
            sign = 1;
    }

    bool isZero() const
    {
        return a.empty() || (a.size() == 1 && !a[0]);
    }

    Int operator-() const
    {
        Int res = *this;
        res.sign = -sign;
        return res;
    }

    Int abs() const
    {
        Int res = *this;
        res.sign *= res.sign;
        return res;
    }

    long long longValue() const
    {
        long long res = 0;
        for (int i = a.size() - 1; i >= 0; i--)
            res = res * base + a[i];
        return res * sign;
    }

    friend Int gcd(const Int &a,const Int &b)
    {
        return b.isZero() ? a : gcd(b,a % b);
    }

    friend Int lcm(const Int &a,const Int &b)
    {
        return a / gcd(a,b) * b;
    }

    void read(const string &s)
    {
        sign = 1;
        a.clear();
        int pos = 0;
        while (pos < (int)s.size() && (s[pos] == '-' || s[pos] == '+'))
        {
            if (s[pos] == '-')
                sign = -sign;
            ++pos;
        }

        for (int i = s.size() - 1; i >= pos; i -= base_digits)
        {
            int x = 0;
            for (int j = max(pos,i - base_digits + 1); j <= i; j++)
                x = x * 10 + s[j] - '0';
            a.push_back(x);
        }
        trim();
    }

    friend istream &operator>>(istream &stream,Int &v)
    {
        string s;
        stream >> s;
        v.read(s);
        return stream;
    }

    friend ostream &operator<<(ostream &stream,const Int &v)
    {
        if (v.sign == -1)
            stream << '-';
        stream << (v.a.empty() ? 0 : v.a.back());
        for (int i = (int)v.a.size() - 2; i >= 0; --i)
            stream << setw(base_digits) << setfill('0') << v.a[i];
        return stream;
    }

    static vector<int> convert_base(const vector<int> &a,int old_digits,int new_digits)
    {
        vector<long long> p(max(old_digits,new_digits) + 1);
        p[0] = 1;
        for (int i = 1; i < (int)p.size(); i++)
            p[i] = p[i - 1] * 10;
        vector<int> res;
        long long cur = 0;
        int cur_digits = 0;
        for (int i = 0; i < (int)a.size(); i++)
        {
            cur += a[i] * p[cur_digits];
            cur_digits += old_digits;
            while (cur_digits >= new_digits)
            {
                res.push_back(int(cur % p[new_digits]));
                cur /= p[new_digits];
                cur_digits -= new_digits;
            }
        }
        res.push_back((int)cur);
        while (!res.empty() && !res.back())
            res.pop_back();
        return res;
    }

    typedef vector<long long> vll;

    static vll karatsubaMultiply(const vll &a,const vll &b)
    {
        int n = a.size();
        vll res(n + n);
        if (n <= 32)
        {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    res[i + j] += a[i] * b[j];
            return res;
        }

        int k = n >> 1;
        vll a1(a.begin(),a.begin() + k);
        vll a2(a.begin() + k,a.end());
        vll b1(b.begin(),b.begin() + k);
        vll b2(b.begin() + k,b.end());

        vll a1b1 = karatsubaMultiply(a1,b1);
        vll a2b2 = karatsubaMultiply(a2,b2);

        for (int i = 0; i < k; i++)
            a2[i] += a1[i];
        for (int i = 0; i < k; i++)
            b2[i] += b1[i];

        vll r = karatsubaMultiply(a2,b2);

        for (int i = 0; i < (int)a1b1.size(); i++)
            r[i] -= a1b1[i];
        for (int i = 0; i < (int)a2b2.size(); i++)
            r[i] -= a2b2[i];

        for (int i = 0; i < (int)r.size(); i++)
            res[i + k] += r[i];
        for (int i = 0; i < (int)a1b1.size(); i++)
            res[i] += a1b1[i];
        for (int i = 0; i < (int)a2b2.size(); i++)
            res[i + n] += a2b2[i];
        return res;
    }

    Int operator*(const Int &v) const
    {
        vector<int> a6 = convert_base(this->a,base_digits,6);
        vector<int> b6 = convert_base(v.a,6);

        vll a(a6.begin(),a6.end());
        vll b(b6.begin(),b6.end());

        while (a.size() < b.size())
            a.push_back(0);
        while (b.size() < a.size())
            b.push_back(0);
        while (a.size() & (a.size() - 1))
            a.push_back(0),b.push_back(0);

        vll c = karatsubaMultiply(a,b);
        Int res;
        res.sign = sign * v.sign;
        for (int i = 0,carry = 0; i < (int)c.size(); i++)
        {
            long long cur = c[i] + carry;
            res.a.push_back((int)(cur % 1000000));
            carry = (int)(cur / 1000000);
        }
        res.a = convert_base(res.a,6,base_digits);
        res.trim();
        return res;
    }

    //Added part.

    friend Int max(const Int &a,const Int &b)
    {
        if (a < b)
        {
            return a;
        }
        return b;
    }

    friend Int max(const Int &a,const int32_t &B)
    {
        Int b = B;
        return max(a,b);
    }

    friend Int max(const Int &a,const int64_t &B)
    {
        Int b = B;
        return max(a,b);
    }

    friend Int min(const Int &a,const Int &b)
    {
        if (a > b)
        {
            return b;
        }
        return a;
    }

    friend Int min(const Int &a,const int32_t &B)
    {
        Int b = B;
        return min(a,const int64_t &B)
    {
        Int b = B;
        return min(a,b);
    }

    friend Int pow(const Int &a,const Int &b)
    {
        Int _c = 1;
        Int _b = b;
        Int _a = a;
        while (_b != 0)
        {
            if (_b % 2)
            {
                _c *= _a;
            }
            _a *= _a;
            _b /= 2;
        }
        return _c;
    }

    friend Int pow(const Int &a,const int32_t &B)
    {
        Int b = B;
        return pow(a,const int64_t &B)
    {
        Int b = B;
        return pow(a,b);
    }

    friend Int sqrt(Int a)
    {
        Int x0 = a,x1 = (a + 1) / 2;
        while (x1 < x0)
        {
            x0 = x1;
            x1 = (x1 + a / x1) / 2;
        }
        return x0;
    }
};
/*
  #######################   THE   BIG   INT   ##########################
  ######################################################################
*/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res