2013-04-22 7 views
0

Convert.ToDecimal에 넣을 때 을 입력하면 부동 소수점 숫자는 1.2999입니다. 숫자를 10 진수로 변환하려는 이유는 반올림을 위해서가 아니라 덧셈과 뺄셈의 정밀도 때문입니다. float can보다 더 큰 숫자를 저장할 수 있기 때문에 십진수 타입이이 숫자를 유지할 수 있다는 것을 알고 있습니다.반올림하지 않고 십진수로 변환

왜 번호가 반올림됩니까? 어쨌든 반올림을 막을 수 있습니까?

편집 : 내 반올림 왜 내가 모르는 당신이 여기 아닌 내 정확한 코드 : 지금 정말 혼란 스러워요

decNum += Convert.ToDecimal((9 * 0.03F) + 0); 

. 디버거에 들어가서 (9 * 0.03F) + 0 부분의 출력을 보면 float으로 0.269999981이 표시되지만 십진수는 0.27로 변환됩니다. 그러나 나는 9의 3 %가 0.27이라는 것을 안다. 그러면 원래의 계산이 정확하지 않고 변환이 단순히 그것을 고치고 있다는 뜻입니까?

젠장, 나는 너무 많은 숫자를 싫어한다!

+0

정상 작동합니다. –

+0

@HosseinNarimaniRad 동의 함. 내 컴퓨터에서 반올림하지 않습니다. –

+3

재생할 수 없습니다. 'Console.WriteLine (Convert.ToDecimal (1.2999));'1.2999'를 출력합니다. – Heinzi

답변

7

일어나는 일이 발생하지 않는 것 같습니다.

이 프로그램 :

using System; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      float f = 1.2999f; 
      Console.WriteLine(f); 
      Decimal d = Convert.ToDecimal(f); 
      Console.WriteLine(d); 
     } 
    } 
} 

인쇄 :

1.2999 
1.2999 

난 당신이 값을 캐릭터 라인으로 변환 할 때 문제가 될 수있다 생각합니다.

아래의 ByteBlast 노트에서 잘못된 테스트 데이터를 입력했을 수도 있습니다.

인쇄 float f = 1.2999999999f;않습니다1.3

그 이유를 사용하여 부동 소수점 값이 충분히 정확하게 1.299999999f을 표현하기 위해 정확하지입니다. 이 특정 값은 1.3으로 반올림되어 끝납니다. 그러나 float 값이 반올림 됨 보다 작음 소수로 변환됩니다.

당신이 대신 floatdouble를 사용하는 경우 (당신이 도달하면 1.299999999999999)

가 이

수정 된 질문을 바탕으로 [편집] , 내가 생각하는 정밀도 더 자리에 이동하지 않는 한,이 발생하지 않습니다 그냥 반올림 오류가 예상되므로 다음을 읽어보십시오.

자세한 내용은 "What Every Computer Scientist Should Know About Floating-Point Arithmetic"을 참조하십시오.

Also see this link (아래 주석에서 Tim Schmelter가 권장).

또 다른주의해야 할 점은 디버거가 약간 다른 숫자를 볼 수 있도록 double.ToString() (또는 이와 동등한 것)과 다른 정밀도로 숫자를 표시 할 수 있다는 것입니다.이외에도


:

Console.WriteLine(1.299999999999999.ToString()); 
Prints 1.3 

:하지만 당신은 "왕복"형식 지정자와 약간의 행운이있을 수 있습니다

Console.WriteLine(1.299999999999999.ToString("r")); 
Prints 1.2999999999999989 

(즉, 몰래하는 작은 8에서 참고 끝에서 두 번째 자릿수)

궁극적 인 정확도를 위해 이미 수행중인 것처럼 the Decimal type을 사용할 수 있습니다. 이는 10 진수로 최적화되었으며 훨씬 더 많은 정밀도를 제공합니다.

그러나 float 또는 double보다 수백 배나 느리며 반올림 오류가 발생할 수 있음을 유의하십시오.

+0

그는 테스트 데이터를 망쳤다 고 생각합니다. '1.2999999999f;를 시도하십시오. –

+0

@ByteBlast :'1.2999999999f'를 사용하면'ToDecimal'도 필요 없습니다 : Console.WriteLine (1.2999999999f);는'1.3'을 출력합니다. 나는'float'이이 수에 대해 충분한 정밀도를 가지고 있다고 생각하지 않는다. – Heinzi

+0

동일합니다. 정확한 출력을 얻었습니다. – Stasel