【问题标题】:why Recusrsive modular exponentiation not equals iterative?为什么递归模幂不等于迭代?
【发布时间】:2014-05-31 17:07:13
【问题描述】:

我已经实现了一个非递归模幂运算

typedef long long uii;
uii modularExponentiation(uii base,uii exponent,uii p)
{
    int result= 1;
    base = base % p;
    while( exponent > 0)
    {
        if (exponent % 2 == 1)
           result = (result * base) % p;
        exponent = exponent >> 1;
        base = (base * base) % p;
    }
    return result;
}

另一个是递归的

uii modularExponentiation(uii base,uii exponent,uii p)
{
    if(exponent == 0)
      return 1;
    int res= modularExponentiation(base,exponent/2,p);
    if(exponent%2 == 0)
        return (res * res)%p;
    else
        return ((res*res)*(base%p))%p;


    return res;
}

但是这两个代码没有产生正确的结果。来自维基百科的迭代代码给出了正确的结果。我在递归版本中做错了什么,我应该怎么做才能修复它?

【问题讨论】:

  • 在哪种情况下递归解决方案会失败?尝试替换 ((resres)*(base%p))%p;与 ((resres%p)*base)%p;

标签: c++ algorithm recursion exponentiation modular-arithmetic


【解决方案1】:

我认为使用int res 而不是uii res 是存在溢出机会的问题。甚至((res*res)*base%p)%p 也会导致溢出。

改进的代码:-

uii modularExponentiation(uii base,uii exponent,uii p)
{
    if(exponent == 0)
      return 1;
    uii res= modularExponentiation(base,exponent/2,p);
    res = (res*res)%p;
    if(exponent%2 == 0)
        return res;
    else
        return (res*(base%p))%p;

}

【讨论】:

  • 您改进的代码有效,但我知道如何,您能解释一下吗? int 部分不是问题。
  • 我基本上做了你做的,溢出的原因是不是内存中没有保存(res*res)%p?
  • @Unbound int 部分是问题,因为当您执行 res*res 时,如果 res 是 int 则将其视为 int 乘法,因此如果将两个大 int 值相乘,则会导致溢出但 long long res将乘以两个 long long 因此不会溢出
  • @Unbound even resresbase%p会导致溢出
猜你喜欢
  • 1970-01-01
  • 2019-03-25
  • 2013-08-25
  • 2021-01-07
  • 2021-11-09
  • 2013-11-16
  • 1970-01-01
  • 2015-03-26
  • 1970-01-01
相关资源
最近更新 更多