2011-02-20 3 views
3

누군가 다음과 같은 설명 할 수 있습니다 System.Numerics.BigInteger?Math.Log10 vs. BigInteger.Log10 동작을 설명 할 수 있습니까?

Console.WriteLine(Math.Log10(100));  // prints 2 
Console.WriteLine(Math.Log10(1000));  // prints 3 (as expected) 

Console.WriteLine((int)Math.Log10(100)); // prints 2 
Console.WriteLine((int)Math.Log10(1000)); // prints 3 (as axpected) 

var bi100 = new BigInteger(100); 
var bi1000 = new BigInteger(1000); 

Console.WriteLine(BigInteger.Log10(bi100));  // prints 2 
Console.WriteLine(BigInteger.Log10(bi1000));  // prints 3 (as axpected) 

Console.WriteLine((int)BigInteger.Log10(bi100)); // prints 2 
Console.WriteLine((int)BigInteger.Log10(bi1000)); // prints 2 ??????? 

Console.WriteLine(Math.Floor(BigInteger.Log10(bi100))); // prints 2 
Console.WriteLine(Math.Floor(BigInteger.Log10(bi1000))); // prints 2 ??????? 

Console.WriteLine(Math.Round(BigInteger.Log10(bi100))); // prints 2 
Console.WriteLine(Math.Round(BigInteger.Log10(bi1000))); // prints 3 (as expected) 

편집 : 나는 그것이 rouding 문제가 있다고 알고 있습니다. 내가 알고 싶습니다 왜 Math.Log10과 BigInteger.Log10의 동작이 다릅니다.

+0

마지막 줄에 코드 주석이 올바르지 않습니다. 3 (적어도 나를 사용하는 경우) –

+0

@Mitch : Corrected. – schnaader

답변

6

정밀도와 반올림 때문입니다.

이 행 3

로 이것을 쓰고

Console.WriteLine((int)BigInteger.Log10(bi1000)); 

Console.WriteLine 반면, 2 값 2.9999999999999996를 라운딩되어 당신이 중간 double 변수를 사용하여, 그 값을 검사 확인할 수

double x = BigInteger.Log10(bi1000); 
Console.WriteLine((int)x); 
+1

downvoter 의견을 남겨주세요. 감사. –

+2

+1이 올바른 대답이기 때문에 – schnaader

+1

-1 "3은 바이너리로 정확하게 표현할 수 없으므로"완전히 거짓입니다. 모든 피연산자도 정확합니다. 그러나 중간 값 중 일부는 로그 함수가 구현되는 방식에 따라 정확하지 않을 수 있습니다. –

-1

다른 표현과 다른 구현. Math.Log10(x)는 (그것이 extern이다 그래서 파악하기 쉽지 않다) 다르게 구현되는 반면

+0

(CW는 나쁜 질문에 대한 나쁜 대답이기 때문에 CW입니다.) – Zooba

+0

왜 나쁜 질문입니까? –

+1

반올림 문제에 관한 질문은 이제까지 행복하게 끝나지 않습니다. –

1

큰 차이가 BigInteger.Log10(x)Math.Log(x)/Math.Log(10)으로 구현된다는 점이다. 그럼에도 불구하고 출력에서 ​​약간의 차이를 유발하는 10 진 로그를 수행 할 때 약간 다른 알고리즘을 사용한다는 것은 분명합니다.

관련 문제