2011-09-26 2 views
1

관련없는 다른 인터넷 포럼에서 주어진 숫자의 제곱근이 정수인지 확인하는 방법에 대한 질문이있었습니다. 지금은 그 자체로 사소한 숙제 문제이지만 모든 상황에서 순진한 접근법이 올바른지 궁금해지기 시작했습니다. 즉 의사에있다 :부동 소수점 반올림 오류로 인해 비 정수의 제곱근이 정수가 될 수 있습니까?

declare x, y as double 
input x 
y = sqrt(x) 
if round(y) = y then 
    output "Is integer" 
else 
    output "Isn't integer" 

이 가능 이러한 x를 입력하는 것입니다, x 자체가 하지만 sqrt(x)하는 것 (A 다른 정수의 사각형이 또는 정수) 정수하지 것 부동 소수점 오류 때문에과 정수가 필요합니까?

답변

8

예 : x가 Machine epsilon 인 경우 x = 1.00 ... 0001을 고려해보십시오. 1.0과 동일하지는 않지만 이진 형식으로 표현할 수 있습니다. 이 수의 제곱근은 1.0이 될 것이고 false poitive가됩니다.

+0

네, 물론! 왜 내가 그걸 생각하지 않았을까? :) –

4

다음 표현할 수있는 부동 소수점 수 1.0 (C에서 nextafter(1.0))의 제곱근은 1.0으로 계산 될 수 있습니다.

0

먼저 숫자가 너무 커서 정밀도가 소수점까지 확장되지 않으면 정수 만 가져올 수 있지만 정확하지는 않습니다. 따라서이 값에 신경 쓰지 않는다고 가정합니다. 케이스.

정확한 결과 : IEE754 플로트가 있으면 테스트하기가 쉽습니다. 완벽한 정수 사각형 인 double을 가져 와서 이진 표현을 1 비트 씩 증분 또는 감소시킨 다음 제곱근이 정확한 정수인지 확인하십시오. 표준 부동 소수점 연산은 마지막 위치에서 정확히 0.5 단위 일 것을 요구합니다. 따라서 정수가 실제로 가장 가까운 표현 가능한 제곱근 일 가능성이 있습니다. 물론

0

는 :

double d = Math.Sqrt(4.000000000000001); 
Console.WriteLine(d == 4); 
Console.WriteLine(d == 2); 

이 (C 번호) 과정 일 1 + 엡실론 의지 등 float로서

False 
True 
0

먹이 X 초래한다. 그러나 비 정사각형 정수의 경우 정수가 충분히 크다는 점을 감안할 때 작동합니다. 예를 들어

(C#을)

ulong i = ulong.MaxValue; // 2^64-1, a non square integer. 
double s = Math.Sqrt(i); // Very nearly 2^32 
bool same = Math.Round(s) == s; // true, s is close enough to 2^32.