1

는 I 비 재귀 멱승 잉여 왜 Recusrsive 모듈러 지수가 반복과 동일하지 않습니까?

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; 
} 

재귀하지만 두 개의 코드가 올바른 결과를 생성하지 않는다. Wikipedia의 반복 코드는 정확한 결과를 제공합니다. 재귀 버전에서 내가 뭘 잘못했는지, 그리고 그것을 해결하기 위해 무엇을해야합니까?

+0

경우에 재귀 솔루션은 실패 하는가? (res (res * res) * (기본 % p)) % p; ((res * res % p) * base) % p; –

답변

1

나는 대신에 int 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; 

} 
+0

향상된 코드가 작동하지만 어떻게 설명 할 수 있었는지 설명 할 수 있습니까? int 부분은 문제가 아니 었습니다. – Unbound

+0

나는 기본적으로 당신이 한 일을했습니다. 오버플로의 원인이 (res * res) % p를 메모리에 저장하지 못하고 있습니까? – Unbound

+0

@Unbound int 부분은 문제가되었습니다. 왜냐하면 res * res 일 때 res가 int이면 int 곱하기로 간주합니다. 따라서 두 개의 큰 int 값이 곱해지면 오버플로가 발생하지만 long long res는 두 개의 long long을 곱합니다. 따라서 no 오버플로 –