如何在 C++ 中将大数字符串转换为整数?

Posted

技术标签:

【中文标题】如何在 C++ 中将大数字符串转换为整数?【英文标题】:How to convert large number strings into integer in c++? 【发布时间】:2017-08-14 07:33:29 【问题描述】:

假设,我在c++ 中输入了一个长字符串数字。我们必须对其进行数值运算。我们需要将其转换为integer 或任何可能的操作方式,这些是什么?

string s="12131313123123213213123213213211312321321321312321213123213213";

【问题讨论】:

鉴于这样的数字不适合“常规”整数类型,您必须自己重新实现所需的操作,或者使用 bignum 库。 【参考方案1】:

看起来你想要处理的数字对于任何标准整数类型来说都很大,所以只是“转换”它不会给你很多。你有两个选择:

    (强烈推荐!) 使用 big integer 库,例如gmp。此类库通常还提供解析和格式化大数字的功能。

    自己实现你的大数字,你可以例如使用 uintmax_t 数组来存储它们。您将不得不实现您自己可能需要的各种算术,而这并不是一件容易的事。为了解析数字,您可以使用 reversed double dabble 实现。例如,这是我不久前用 C 编写的一些代码,您可能可以按原样使用它,但是您需要提供一些辅助函数,并且您可能希望使用 C++ 工具重写它,例如std::string 并将此处使用的 struct 替换为 std::vector -- 只是为了记录这个概念

    typedef struct hugeint
    
        size_t s;       // number of used elements in array e
        size_t n;       // number of total elements in array e
        uintmax_t e[];
     hugeint;
    
    hugeint *hugeint_parse(const char *str)
    
        char *buf;
    
        // allocate and initialize:
        hugeint *result = hugeint_create();
    
        // this is just a helper function copying all numeric characters
        // to a freshly allocated buffer:
        size_t bcdsize = copyNum(&buf, str);
    
        if (!bcdsize) return result;
    
        size_t scanstart = 0;
        size_t n = 0;
        size_t i;
        uintmax_t mask = 1;
    
        for (i = 0; i < bcdsize; ++i) buf[i] -= '0';
    
        while (scanstart < bcdsize)
        
            if (buf[bcdsize - 1] & 1) result->e[n] |= mask;
            mask <<= 1;
            if (!mask)
            
                mask = 1;
                // this function increases the storage size of the flexible array member:
                if (++n == result->n) result = hugeint_scale(result, result->n + 1);
            
            for (i = bcdsize - 1; i > scanstart; --i)
            
                buf[i] >>= 1;
                if (buf[i-1] & 1) buf[i] |= 8;
            
            buf[scanstart] >>= 1;
            while (scanstart < bcdsize && !buf[scanstart]) ++scanstart;
            for (i = scanstart; i < bcdsize; ++i)
            
                if (buf[i] > 7) buf[i] -= 3;
            
        
    
        free(buf);
        return result;
    
    

【讨论】:

【参考方案2】:

最好的办法是使用大数计算库。

最好的之一是GNU Multiple Precision Arithmetic Library

解决问题的有用函数示例::

Function: int mpz_set_str (mpz_t rop, const char *str, int base)

从 str 中设置 rop 的值,str 是 base 中以 null 结尾的 C 字符串 根据。字符串中允许有空格,但会被忽略。

基数可以在 2 到 62 之间变化,或者如果基数为 0,那么前导 使用字符:0x 和 0X 用于十六进制,0b 和 0B 用于二进制, 0 表示八进制,否则为十进制。

对于不超过 36 的基数,忽略大小写;大写和小写字母 具有相同的价值。对于基数 37 到 62,大写字母表示 通常的 10..35 而小写字母代表 36..61。

如果整个字符串是基数中的有效数字,则此函数返回 0 根据。否则返回 -1。

文档:https://gmplib.org/manual/Assigning-Integers.html#Assigning-Integers

【讨论】:

【参考方案3】:

如果字符串包含小于std::numeric_limits&lt;uint64_t&gt;::max() 的数字,则std::stoull() 是最好的意见。

unsigned long long = std::stoull(s);

C++11 及更高版本。

【讨论】:

以上是关于如何在 C++ 中将大数字符串转换为整数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中将数字转换为字符串,反之亦然

在 C++ 中将字符转换为整数

如何在 C++ 中将字符串转换为 const char[]

如何在 C++ 中将字符串转换为 int?

如何在 C++ 中将数字字符串转换为 int 数组 [重复]

如何在 C++ 中将字符的十进制代码转换为 Unicode 字符串?