使用mod和pow计算大数字

时间:2016-04-13 10:45:03

标签: c++ pow cmath mod

我试图使用以下代码解决大模型问题。

#include<iostream>
#include<cmath>

using namespace std;

typedef long int li;

li m;
li mod(li b,li p)
{
    if(p==0)
        return 1;
    if(p%2==0)
    {
        return ((mod(b,p/2)%m)*mod(b,p/2)%m)%m;
        //return (li)pow(mod(b,p/2)%m,2)%m;
    }
    return (b%m*mod(b,p-1)%m)%m;
}

main()
{
    li b,p;
    while(cin>>b>>p>>m)
    {
        cout<<mod(b,p)<<endl;
    }
}

但它给((mod(b,p / 2)%m)* mod(b,p / 2)%m)%m和pow(mod(b,p / 2)%m, 2)%mi想知道它们是不一样的,如果它们是为什么给出不同的输出。

示例输入: 3 18132 17

17 1765 3

2374859 3029382 36123

没有pow功能的输出: 13 2 13195

输出功能:

1 2 31329

带有pow功能的测试代码

#include<iostream>
#include<cmath>
using namespace std;

typedef long int li;

li m;
li mod(li b,li p)
{
    if(p==0)
        return 1;
    if(p%2==0)
    {
        //return ((mod(b,p/2)%m)*mod(b,p/2)%m)%m;
        return (li)pow(mod(b,p/2)%m,2)%m;
    }
    return (b%m*mod(b,p-1)%m)%m;
}

main()
{
    li b,p;
    while(cin>>b>>p>>m)
    {
        cout<<mod(b,p)<<endl;
    }
}

1 个答案:

答案 0 :(得分:0)

您报告的“没有pow功能”的答案是正确的答案,您的代码看起来还不错。所以我认为你的问题在于你正在应用的测试,而不是你的模幂运算。

pow函数对(双精度)浮点数进行操作,即使两个输入都是小整数,也不能保证给出精确的结果。你发生的事情是,在某些时候pow返回的值只是一个小于整数的值,然后你把它投射到long int并获得比你小1的值“应该“,之后一切都是错的。

例如,如果你用你的代码计算3 ^ 6 mod 17,那么在一个点它得到3 ^ 3 mod 17 = 10(OK到目前为止),然后计算pow(10,2)...和,至少在我的机器上使用我的编译器,这只是略低于100.所以转换为li得到99而不是100,然后我们就死了。

我试图通过检测代码输出中间值来更详细地验证这一点,但有趣的是,由于浮点运算的细微之处,这通常会失败。 (在变量中保存一个中间值可能会导致它受到额外的浮点舍入,这会将刚好小于整数的值转换为精确的整数值。)