2009-05-19 6 views
6

Im 현재 Code Complete, Steve McConnell, 특히 부동 소수점 수 295 페이지를 읽는 중입니다. 인쇄 증분 0.1 in C#

는 다음 코드 실행시 : 0.9 1.0 수가 다른 I가 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 에서 인쇄를 얻었다

 double nominal = 1.0; 
     double sum = 0.0; 

     for (int i = 0; i < 10; i++) 
     { 
      sum += 0.1; 
      Console.WriteLine("sum: " + sum.ToString()); 
     } 

     if (equals(nominal,sum)) 
     { 
      Console.WriteLine("Numbers are the same"); 
     } 
     else 
     { 
      Console.WriteLine("Numbers are different"); 
     } 

어째서 나는 ' 일어날 것으로 예상되는 출력을 얻지 못합니까? 예 : 0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.79999999999999999 0.89999999999999999 0.99999999999999999 숫자 내가 문자열로 이중에서 암시 적 변환을 수행 할 때

는 C#을 반올림 번호가 다르다? 나는 응용 프로그램을 디버깅하고 for 루프를 통해 단계를 수행 할 때 반복 종료되지 않는 십진수를 볼 수 있기 때문에 그렇게 생각합니다. 어떻게 생각해? 나는 옳은가 틀린가?

답변

12

double.ToString()은 정밀도가 지정되지 않은 경우 기본값 15 진수로 설정된 일반 형식을 사용합니다. 그래서 당신이보고있는 것을보고있는 이유는 약간의 반올림을하는 것입니다. 예를 들어 귀하의 질문에 명시된 0.89999999999999999는 소수점 이하 17 자리입니다. 너는 실제로 sum.ToString("g17")을해서 전체 수를 볼 수 있었다.

당신은 그물의 표준 숫자 형식 문자열과 여기에 기본 정밀도 찾을 수 있습니다 : 그것은이다 http://msdn.microsoft.com/en-us/library/dwhawy9k(VS.80).aspx

+0

감사합니다. 나는 당신에게 주어진 결과물로 매우 정확해야했습니다. 내가 0.79999999999999999와 같은 긴 십진수를 주었을 때, 나는 사용하고 있던 자리수에주의를 기울이지 않았다. – burnt1ce

2

이를 toString 기본 동작에서입니다. 디버거에서 합계를 보면 당신은 ToString을 통해 라우팅없이 당신에게 값을 표시하는이 얻을 :

0.0 
0.1 
0.2 
0.30000000000000004 
0.4 
0.5 
0.6 
0.7 
0.79999999999999993 
0.89999999999999991 

당신이 예상하는대로 기본 동작임을 나타냅니다.

HTH

2

짧은 대답은 : 그것은, 부동 소수점 그래서 아무것도 기대하지 않는 있지만 ("오른쪽"의 적절한 값) 옳다! 대답이 길수록 부동 소수점이 어떻게 작동하는지 사람들이 부동 소수점을 사용하여 작업하는 방식을 이해해야합니다. IIRC GNU printf (그리고 다른 사람들이 생각하기로는) 특별한 경우는 "정말 근사한 10 진수에 가깝습니다".