2012-07-06 3 views
7

나는 다음 기능을 가지고있다.C# isPowerOf 기능

나는 함수를 호출하는 경우 : 나는 16807를 호출하는 경우

isPowerOf(25, 2) 

그것은, 5^2가 25 동일하기 때문에 true를 반환하지만, 7^5이며, 다음 방법이에서

isPowerOf(16807, 5) 

을 경우 '7'을 인쇄하지만 a == (int)a은 false를 반환합니다.

도와 주시겠습니까? 감사!

+6

[모든 컴퓨터 과학자가 부동 소수점 연산에 대해 알아야 할 사항] (ko-ko/e19957-01/806-3568/ncg_goldberg.html)에 대한 필수 링크 – AakashM

+1

누구나 잘 제안 할 것입니다. 부동 소수점 비교,하지만 IMO 문제의 근원은 여기에 알고리즘입니다. – harold

답변

6

반올림 오류를 작은 엡실론를 사용해보십시오 :

return Math.Abs(a - Math.Round(a)) < 0.0001; 
:

해롤드 제안으로
return Math.Abs(a - (int)a) < 0.0001; 

,이 경우 a을 라운드하는 것이 더있을 것은, 정수 값보다 약간 작을 수 3.99999처럼 일어나는

+0

지금은 작동하지만 어떻게 되니? 7 = (int) 7? – Novak

+0

@GuyDavid : 반올림 오류 때문에 숫자가 7이 아니지만 7.000000001이거나 이와 비슷합니다. – Dani

+0

@Guy David try : Console.WriteLine ((int) a); –

2

당신은 코드를 디버깅하고 먼저 비교하여 볼 수있는 경우 :

isPowerOf(25, 2) 

A가 들고 5.0 여기에 5.0 == 5 => 당신이

을 사실 얻을 이유 즉, 2 isPowerOf(16807, 5)

에서이

7.0000000000000009 != 7 이후 => false를 받고 7.0000000000000009을 들고있다. 및 Console.WriteLine (a)는 이중 반올림 만이

2

Math.Powdouble의에서 작동 대니의 솔루션에 같은 가장 가까운 값을 비교해야하는 이유 즉 7

을 보여/절단되기 때문에 반올림 오류에 와서 뿌리를 가지고 놀 때. 당신은 당신이 정확한 전력 발견했습니다 확인하려면 다음

  • 루트를
  • 라운드를 추출하는 등 현재 Math.Pow을 수행을 가장 가까운 정수
  • 올리고이 정수 결과 제공된 전원을 확인하고 제공된 대상을 확인하십시오. 문제를 해결
5

비교 제안 된 힘을 정수로 상승 할 때 Math.Powint의 범위의 숫자에 대한 정확한 될 것입니다,하지만 여기에 실제로 문제입니다 부동 소수점 모든에 참여하지 않아야한다는 것입니다. 본질적으로 부정확 한 측정에 대한 계산의 근사가 아닌 정수와 관련된 질문에 대한 정확한 답을 원합니다.

다른 방법으로이 작업을 수행 할 수 있습니까?

double guess = Math.Pow(num, 1.0/power); 
return num == exponentiateBySquaring((int)guess, power) || 
     num == exponentiateBySquaring((int)Math.Ceil(guess), power); 
     // do NOT replace exponentiateBySquaring with Math.Pow 

그것은만큼 guess 1 오프보다가 같이 작동합니다 :

마음에 오는 첫번째 것은 속임수이다. 하지만 그 조건이 항상 충족되지는 않기 때문에 입력 내용에 대해 항상 작동한다는 것을 보장 할 수는 없습니다.

그래서 여기에 마음에 오는 다음 일이 : exponentiateBySquaring(base, power)에서 base에 대한 이진 검색 (먼저 상단 경계를 검색 변형)하는 결과가 num에 가장 가까운 것입니다. 가장 가까운 답이 num 일 때만 (그리고 둘 다 정수이므로 비교가 깨끗합니다) numpower입니다. 오버플로가 없으면 (항상 없어야 함) 항상 작동해야합니다.

+0

예, 정수와 부동 소수점 숫자가 각각 다른 유형 인 이유가 있습니다. –