2017-09-20 21 views
3

제가여부 POW (a, b) %의 B == C에서

POW가 (a, b) % B는

를 == 여부를 확인하고 싶은 (오버플로 없음)

은 2 ≤ b ≤ 32768 (2)이고 2 ≤ a ≤ b이고 a와 b는 정수임.

그러나 b가 큰 숫자 인 pow(a, b) % b을 직접 계산하면 C가 빠르게 오버플로됩니다. 이 조건이 성립 하는지를 확인하는 트릭/효율적인 방법은 무엇입니까?

이 질문은 Fermat의 작은 정리에 대한 증인을 찾는 것을 기반으로합니다.이 정리는 Fermat의 작은 정리가 거짓이면 b가 소수가 아님을 나타냅니다.

또한 걸리는 시간이 제한되어 있으므로 너무 느려서는 안됩니다 (2 초 또는 그 이상). 가장 큰 Carmichael 번호 인 소수 b은 소수가 아니지만 을 2 <= a <= b (b < = 32768)으로 만족하지 않습니다. 따라서 pow(a, b) % b == a2 <= a <= 29341으로 확인하는 방법이 너무 느려서는 안됩니다.

+3

의'^ 당신은'A' 전원'b' 또는 A''의'비트 XOR'와'b'에 제기 의미 b'? –

+0

@AjayBrahmakshatriya 나는 그가 힘을 의미한다고 생각한다. 그렇지 않으면 오버플로를 얻는 것이 훨씬 어렵 기 때문이다. 그러나 C에서'^'는 보통 XOR이므로 확실하게 말하기는 어렵습니다. – izlin

+0

@izlin 나는 그가 힘을 의미한다고 생각했지만 나는 분명히 해달라고 부탁했다. –

답변

5

Exponentiation by squaring 방법을 사용할 수 있습니다.

아이디어는 다음 바이너리 형식으로

  • 분해 b하고 제품을 우리가 항상 32768 이하 %b를 사용
  • 공지 사항을 분해하기 때문에 발생합니다 32 비트 수에 항상 적합 .

그래서 C 코드는 다음과 같습니다

으로
/* 
* this function computes (num ** pow) % mod 
*/ 
int pow_mod(int num, int pow, int mod) 
{ 
    int res = 1 

    while (pow>0) 
    { 
     if (pow & 1) 
     { 
      res = (res*num) % mod; 
     } 
     pow /= 2; 
     num = (num*num)%mod; 
    } 

    return res; 
} 
+0

이것은 실제로 작동합니다! 나는 이것을 이미 보았지만 그것을 구현하는 데 어려움을 겪었습니다, 이것이 효과가있는 것 같습니다! (하지만 잊어 버린 후, res = 1 :). 고맙습니다! – Isaiah

+1

데이터 형식 ('short' 또는'unsigned short', 입력 매개 변수, 반환 형식 및'res' 데이터 형식을'unsigned long int' 또는'long int') 외에도보기 좋게 보입니다. 아마도'res = (res * num) % mod' 주위에 중괄호를 쓸 수도 있습니다. +1. –

+0

코너 케이스 실패 :이'pow_mod (num, 0, 1)'-> 1 그리고 0이어야합니다. 변경 제안 :'int res = 1 % mod;'. 그러나 OP는 다음과 같이 말했습니다 : 2 ≤ a ≤ b. – chux

3

Z/bZ에서 모듈러 산술 연산을 수행하고 있습니다.

참고하는 몫환에서 요소의 클래스의 n 번째 전력 소자의 n 승의 클래스이기 때문에, 우리는 다음과 같은 결과가 :

(a^b) mod b = ((((a mod b) * a) mod b) * a) mod b [...] (b times) 

을 그래서, 당신은 큰 정수 라이브러리가 필요하지 않습니다.

당신은 단순히 다음의 알고리즘 (의사 코드)를 사용하여 C 프로그램을 작성할 수 있습니다

  • 정수로 변수 a와 b를 선언합니다.
  • a로 초기화되는 임시 변수 temp를 사용하십시오.
  • b 단계가있는 루프를 수행하고 각 단계에서 (temp * a) mod b을 계산하여 새 임시 값을 얻습니다.
  • 결과를 a와 비교하십시오. 이 공식으로

, 당신은 온도의 최대 값은 32768입니다 것을 볼 수 있습니다, 그래서 당신은 저장 온도에 정수를 선택할 수 있습니다.

+1

이 알고리즘의 반복 횟수는'b' 곱셈이 될 것이고 이것은 매우 나쁘다. square-and-multiply 알고리즘은'log2 (b)'squarings과'hammingWeight (b)'(또한 최대 log2 (b)) 곱셈의 복잡성을 달성합니다. 'b = 32768' 일 때 알고리즘은'32768' 반복을 필요로하는 반면, 간단한 SQ + MUL은 15 번의 반복이 필요합니다. –

+0

네, 당신 말이 맞습니다. 당신이 말했듯이, 질문에서 주요 목표를 달성하는 ** 가장 단순한 ** 알고리즘을 보여주고 싶었습니다. C에서 오버플로가 발생하지 않는 것입니다. 물론 이것은 가장 빠른 알고리즘이 아닙니다. –

+0

@ AlexandreFenyo 정말 고마워요! 그러나, 나는 또한 그것이 걸리는 시간에 제한되어있다. b의 한도 내에서 가장 큰 카 마이클 수 (소수 b가 아니지만 소수 (a, b) % b == a를 2 <= a <= b로 채우지 않음)는 29341이며이 방법은 29341을 반복해야하는데, 상당히 느립니다. – Isaiah