2009-03-01 2 views
9

화폐 금액을 저장하는 데 사용되는 특정 데이터 유형의 위험에 대한 몇 가지 기사를 읽었습니다. 불행히도, 일부 개념은 내 안락 영역에 있지 않습니다.C#에서 화폐 금액을 처리하기위한 모범 사례

이 기사를 읽은 후에 C#으로 돈을 사용하기위한 모범 사례 및 권장 사항은 무엇입니까? 소량의 경우 특정 데이터 유형을 사용해야하고 더 많은 금액의 경우 다른 데이터 유형을 사용해야합니까? 또한 나는 영국에 본사를두고 있는데 이는 우리가 사용하는 것을 의미합니다 (예 : 4,000 파운드, 다른 문화권은 같은 금액을 다르게 나타냄).

답변

8

반올림 오류로 인해 부동 소수점 숫자를 사용하지 마십시오. 10 진수 유형이 적합해야합니다.

+0

누군가가 이것을 왜 투표했는지 궁금 할 것 같습니다. –

+0

아래 투표를 상쇄하기 위해 투표했습니다. 나는 아래 표결이 코멘트없이 허용되어야한다고 생각하지 않는다. –

2

값 개체를 사용하여 금액 (decimal)과 통화를 모두 보유합니다. 이렇게하면 다른 통화로 동시에 작업 할 수 있습니다. decimal은 .NET에서 돈을 지불하는 데 권장되는 데이터 형식입니다.

16

십진수는 화폐 금액에있어 가장 현명한 유형입니다.

십진수는 소수점 이하 28 자리 + 소수점 이하 10 자리 숫자입니다. Decimal을 사용하면 기본 2 Double 유형을 사용할 때보다는 놀라움이 적습니다.

Double은 많은 일반적인 부동 소수점 연산을위한 CPU 하드웨어로 인해 Decimal 및 Double과 같은 메모리를 사용하는 것이 훨씬 빠르지 만 대부분의 기본 10 분수 (예 : 1.05)를 정확하게 나타내지는 못하며 정확도가 떨어집니다 + 정밀도의 10 진수. Double은 더 많은 범위 (더 크고 작은 수를 나타낼 수 있음)의 이점을 가지고 있으며 일부 계산, 특히 일부 통계 계산에 유용 할 수 있습니다.

Decimal은 4 자리 10 진수로 고정 소수점입니다. 그렇지 않다. 당신이 의심하는 경우, 다음 코드 줄이 0.0000000001 산출 통지 :

Console.WriteLine("number={0}", 1m/10000000000m); 

그 모든 말한다면, 흥미 롭다 즉, Microsoft Excel에서 화폐 양의 작업을위한 세계에서 가장 널리 사용되는 소프트웨어 , double을 사용합니다. 물론, 그들은 잘 작동되도록 많은 농구를 뛰어 넘어야하며, 여전히 원하는 것을 남겨 둡니다. 엑셀이 두 식을 시도

  • 을 1-0.9-0.1 =
  • = (1-0.9-0.1)

를 제 수율 0 번째 ~ 수율 -2.77e-17 . 엑셀은 실제로 어떤 경우에는 숫자를 더하거나 뺄 때 숫자를 마사지하지만 모든 경우에는 그렇지 않습니다.

+0

깔끔한 Excel 예제! –

+0

돈을위한 10 진수가 좋습니다. 그러나 돈의 비율은 여전히 ​​두 배가되어야합니다 (예 : 이자율). – Richard

6

Martin Fowler는 Money class을 사용하도록 권장합니다. 이론적 근거는 링크를 참조하십시오. 저기서 그의 아이디어를 구현 한 사례가 많이 있거나 자신의 의견을 쓸 수도 있습니다. 파울러 자신의 구현은 자바로 구현되므로 클래스를 사용합니다. 내가 본 C# 버전은 합리적인 것처럼 보이는 구조체를 사용합니다.

0

부서가 필요한 경우 다른 사람들이 권장하는대로 10 진수를 사용하는 것이 좋습니다. 간단한 계산 응용 프로그램의 경우 Integer 형식을 사용하는 것이 좋습니다. 두 가지 유형 모두, 나는 항상 최저 화폐 단위로 일할 것입니다. (예 : 캐나다/미국의 센트)

나는 @dangph가 추가 한 파울러의 머니 콜 이론을 좋아합니다.

0

무엇을 하든지 응용 프로그램의 각 계층에서 통화 금액을 처리하는 방법을 이해해야합니다.

SQLServer 및 .Net에서 통화를 반올림하는 여러 가지 방법을 사용하고 응용 프로그램이 특정 유형의 계산을 처리하는 방식이 일관 적이 지 않았기 때문에 한 번씩 1 ¢ 오류를 추적하는 데 일주일이 걸렸습니다. in .net. 관심이 있으시면 "bankers' rounding"을 찾으십시오.

통화를 포맷하는 것과 관련된 문제가 있습니다. 영국 이외의 금액, 다른 언어/문화 등을 처리해야할지 모르지만 다른 수준의 복잡성이 추가됩니다.

+0

주의해야 할 또 다른 문제는 SQL Server가 DATETIME을 3.33 밀리 초 (0.0033 초)의 정밀도로 저장한다는 것입니다. 나는 그것이 나의 목적을 위해 충분하지 않았기 때문에 한때 이것을 조금 낫게했다. – ahsteele

0

귀하의 질문에 적절한 데이터 유형을 사용하는 것 이외에 귀하의 프로그램이 통화 변환을 얼마나 잘 처리하는지가 중요합니다. 물론이 문제는 통화에만 국한되지 않습니다. Jeff AtwoodThe Turkey Test의 성과를 요약 한 훌륭한 글을 올렸습니다.