C ++中的长数字

时间:2015-07-05 06:32:43

标签: python c++ math long-integer

我在Python中有这个程序:

# ...
print 2 ** (int(input())-1) % 1000000007

问题是这个程序在大数字上运行了很长时间。我用C ++重写了我的代码,但有时我得错了答案。例如,在数字12345678的Python代码中,我有749037894并且它是正确的,但在C ++中我有-291172004

这是C ++代码:

#include <iostream>
#include <cmath>
using namespace std;
const int MOD = 1e9 + 7;

int main() {
    // ...
    long long x;
    cin >> x;
    long long a =pow(2, (x-1));
    cout << a % MOD;
}

4 个答案:

答案 0 :(得分:2)

如前所述,您的问题是对于大指数,您有整数溢出。

为了克服这一点,请记住模块化乘法具有以下特性:

  

(A * B)mod C =(A mod C * B mod C)mod C

然后你可以使用快速求幂方案实现'e to power p modulo m'功能。 假设没有负面力量:

long long powmod(long long e, long long p, long long m){
    if (p == 0){
        return 1;
    }
    long long a = 1;
    while (p > 1){
        if (p % 2 == 0){
            e = (e * e) % m;
            p /= 2;
        } else{
            a = (a * e) % m;
            e = (e * e) % m;
            p = (p - 1) / 2;
        }
    }
    return (a * e) % m;
}

请注意,在每次乘法后都会进行余数处理,因此如果单次乘法不会溢出,则不会发生溢出(1000000007的{​​{1}}和m都是如此。< / p>

答案 1 :(得分:0)

您似乎正在处理正数,而且这些数字超出了您为其存储分配的位数。还要记住,Python和C / C ++之间的区别在于计算负值的模数。要获得类似的计算,您需要将模数添加到值中,以便在采用模数之前它是正面的,这是它在Python中的工作方式:

cout << (a+MOD) % MOD;

在获取模数之前,您可能需要添加MOD n次,直到临时值为正。

答案 2 :(得分:0)

许多其他答案都提到过,你的问题在于整数溢出。

你可以像deniss建议的那样做,并实现你自己的modmul()和modpow()函数。

但是,如果这是一个项目的一部分,需要进行大量的大量计算,我建议使用一个&#34;大数字库&#34;例如GNU GMPmbedTLS Bignum library

答案 3 :(得分:0)

在C ++中,各种基本类型都有固定的大小。例如,long long通常为64位宽。但宽度因系统类型和其他因素而异。如上所述,您可以查看climits.h以了解您的特定环境的限制。

将2增加到12345677的功率将涉及将二进制数10向左移位12345676位,这将不适合64位long long(我怀疑不太适合long long实施)。

要考虑的另一个因素是pow会返回double(或long doubledepending on the overload used。您没有说出您正在使用的编译器,但是当调用pow的结果被分配给long long变量a时,您很可能会收到有关可能的截断或数据丢失的警告

最后,即使pow返回一个long double,我怀疑指数12345677太大而无法存储在long double中,因此pow可能会返回正无穷大,然后被截断一些适合long long的位模式。您当然可以通过引入中间long double变量来检查它,以接收pow的值,然后您可以在调试器中检查它。