在c ++中乘法溢出

时间:2016-04-05 21:35:23

标签: c++ algorithm overflow

在我的代码中,我试图将两个数相乘。算法很简单,因为(k)*(k-1)^ nI将乘积(k-1)^ n存储在变量p1中,然后我将它乘以k 。对于n = 10,k = 10(k-1)^ n-1应该是387420489并且我在变量p1中得到它,但是在它乘以k,我得到一个负数。我使用modulous而不是3874208490,i得到一些其他大的正数。什么是正确的方法?

#include <iostream>

using namespace std;

typedef long long ll;

ll big = 1000000000 + 7;

ll multiply(ll a, ll b)
{
    ll ans = 1;
    for (int i = 1; i <= b; i++)
        ans = ans * a;
    return ans % big;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        ll n, k;
        cin >> n >> k;
        ll p1 = multiply(k - 1, n - 1);
        cout << p1 << endl; // this gives correct value
        ll p2 = (k % big) * (p1 % big);
        cout << ((p2 + big) % big) % big << endl;
    }
}

2 个答案:

答案 0 :(得分:0)

什么是ll类型?如果它只是int(并且我很确定它是),它会溢出,因为32位有符号类型不能存储超过(2 ^ 31)-1的值,大约等于2 * 10 ^ 9。您可以使用long long int使其正常工作,然后您的代码将使用小于2 ^ 63的结果。

答案 1 :(得分:0)

你得到溢出并不奇怪。我将你的方程式插入到wolfram alpha中,将n固定为10,并将k从0重复到100。

曲线非常垂直,在k = 80附近非常快。

10 ^ 21需要70个二进制位来表示它,而你只有63个长长的。

您将不得不决定此算法参数的限制,并选择相应的数据类型。也许双人会更合适?

link to plot is here