C #에서 돈을 위해 사용하는 가장 좋은 데이터 유형은 무엇입니까?


426

C #에서 돈을 위해 사용하는 가장 좋은 데이터 유형은 무엇입니까?


4
게시물의 답변이 도움 이 될 수 있습니다 .
ntombela

다음은 모든 데이터 유형에 대한 매핑입니다. docs.microsoft.com/en-us/dotnet/framework/data/adonet/…
JohnLBevan

또한 데이터 주석을 사용하는 경우 다음을 포함하십시오 using System.ComponentModel.DataAnnotations;. [DataType(DataType.Currency)] msdn.microsoft.com/en-us/library/…
JohnLBevan

답변:


422

십진수 로 다음과 같이 설명 됩니다.

decimal 키워드는 128 비트 데이터 형식을 나타냅니다. 부동 소수점 유형과 비교하여 10 진수 유형은 정밀도와 범위가 작기 때문에 재무 및 금전적 계산에 적합합니다 .

다음과 같이 소수를 사용할 수 있습니다.

decimal myMoney = 300.5m;

41
그 링크에 대해 중요한 점을 설명해야합니다. 답변은 추가 참조 또는 세부 정보로 연결되는 링크만으로도 충분해야합니다. 참조 stackoverflow.com/help/how-to-answer
TheRubberDuck

2
따라서 최소 길이 대답은 최소 길이 주석보다 문자 수가 적을 수 있습니다. 흥미 롭습니다! 내가 간결하고 간결한 답변에 문제가있는 것은 아닙니다. 특히 그것이 더 깊이 논의되어 더 자세한 논의로 연결되는 경우에 특히 그렇습니다.
B. Clay Shannon

3
놀라운 답변이며 질문에 완전히 대답하기 때문에 추가 설명이 필요하지 않습니다. MSDN 문서에 대한 링크는 내가 생각하는 한 보너스입니다. 브라보!
trnelson

@Leee Treveil, 돈은 얼마입니까 (9.0098) 포인트 뒤 4 문자를 의미
SAR

114

시스템. 소수

10 진수 값 유형은 양수 79,228,162,514,264,337,593,543,950,335에서 음수 79,228,162,514,264,337,593,543,950,335 범위의 십진수를 나타냅니다. 10 진수 값 유형은 많은 유효 정수 및 소수 자릿수가 필요하고 반올림 오류가없는 재무 계산에 적합합니다. 십진법 유형은 반올림의 필요성을 제거하지 않습니다. 오히려 반올림으로 인한 오류를 최소화합니다.

왜 double을 사용해서는 안되는지에 대한 zneak의 훌륭한 답변 을 지적하고 싶습니다 .


68

Enterprise Application Architecture의 패턴 에서 Money 패턴 을 사용하십시오 . 금액을 소수로 지정하고 통화를 열거 형으로 지정하십시오.


2
실제로 이것을 제안하려고했지만 Currency를 클래스로 만들어 환율을 정의 할 수 있습니다 ( "기본 통화", 종종 미국 달러 (환율 1.00으로 설정)).
Thomas Owens

5
이 스레드의 미래 방문자 (나처럼)가 이제 nuget.org/packages/Money 에 있습니다.
Korijn

그러한 유형이 구조체 또는 클래스인지 궁금합니다. 10 진수 + (int) 열거 형은 20 바이트입니다. 내 돈은 아직 구조 중입니다.
nawfal

Money너겟에는 프로젝트 사이트에 대한 죽은 github 링크가 있습니다 ... 문서가 없습니까?
George Mauer 17

이것의 문제는 당신이 당신의 자신의 구현을 만들고 있다면 실제로 그것을 유지하는 방법을 알아 내야한다는 것입니다. 가장 인기있는 ORM (EF)은 사용자 정의 데이터 유형을 전혀 지원하지 않습니다. 따라서 누군가가 도착하도록 요청 정말 아주 간단한 일이 될 해야하는지 할 잡초에 깊은.
George Mauer

25

소수. double을 선택하면 반올림 오류가 발생합니다.


8
@Jess double는 부동 소수점이 모든 숫자를 정확하게 표현할 수 없기 때문에 반올림 오류가 발생할 수 있습니다 (예 : 0.01은 부동 소수점에 정확한 표현이 없음). Decimal반면에, 않는 숫자를 표현 정확하게 . (상충 관계는 Decimal부동 소수점보다 작은 범위를 갖습니다.) 부동 소수점은 실수로 반올림 오류를 발생시킬 수 있습니다 (예 :) 0.01+0.01 != 0.02. Decimal반올림 오류를 줄 수 있지만 요청한 경우에만 (예 : Math.Round(0.01+0.02)0을 반환)
Ian Boyd

2
@IanBoyd : "$ 1.57"값을 정확하게 두 배로 표현할 수 있습니다 (157). double적절한 경우 스케일링 및 도메인 별 반올림을 사용 하고 신중하게 적용하면 완벽하게 정확할 수 있습니다. 하나의 반올림에서 느슨해지면 decimal의미 적으로 잘못된 결과를 얻을 수 있습니다 (예 : 가장 가까운 페니로 반올림되어야하지만 실제로는 먼저 주변에 있지는 않은 여러 값을 더한 경우). 유일한 좋은 점은 decimal스케일링이 내장되어 있다는 것 입니다.
supercat

1
@ supercat,이 의견에 대해 "가장 가까운 페니로 반올림되어야하지만 실제로 먼저 주변에 있지 않은 여러 값을 더하면 플로트가 어떻게 이것을 해결할 수 있는지 알 수 없습니다. 사용자 오류이며 10 진수 IMHO와 관련이 없습니다. 나는 요점을 얻지 만 주로 IanBoyd가 그것을 지정했기 때문에 그것이 잘못 배치되었다고 생각합니다 ... 요청하면.
sawe


13

Money 패턴에 동의하십시오 : 10 진수를 사용할 때 통화 처리는 너무 번거로울 수 있습니다.

Currency 클래스를 만들면 올바른 ToString () 메서드, 구문 분석 값 제어 및 더 나은 나누기 제어를 포함하여 돈과 관련된 모든 논리를 넣을 수 있습니다.

또한 Currency 클래스를 사용하면 실수로 돈을 다른 데이터와 혼합 할 가능성이 없습니다.


10

또 다른 옵션은 (특히 자신의 클래스를 롤링하는 경우) int 또는 int64를 사용하고 하위 4 자리 (또는 가능하면 2)를 "소수점의 오른쪽"으로 지정하는 것입니다. 따라서 "가장자리에"들어가는 길에 "* 10000", 나가는 길에 "/ 10000"이 필요합니다. 이것은 Microsoft SQL Server에서 사용하는 저장 메커니즘입니다. http://msdn.microsoft.com/en-au/library/ms179882.aspx를 참조하십시오 .

이것의 핵심은 (빠른) 정수 산술을 사용하여 모든 합계를 수행 할 수 있다는 것입니다.


7

내가 함께 일한 대부분의 응용 프로그램 decimal은 돈을 나타내는 데 사용 됩니다. 이는 응용 프로그램이 둘 이상의 통화와 관련이 없다는 가정을 기반으로합니다.

이 가정은 다른 통화를 사용하는 다른 국가에서는 응용 프로그램을 사용하지 않을 것이라는 또 다른 가정을 기반으로 할 수 있습니다. 나는 그것이 틀린 것으로 판명 된 경우를 보았다.

이제 가정은 새로운 방식으로 도전하고 있습니다. 비트 코인과 같은 새로운 통화가 점점 보편화되고 있으며 특정 국가에 국한되지 않습니다. 한 국가에서만 사용되는 응용 프로그램이 여전히 여러 통화를 지원해야 할 수도 있습니다.

어떤 사람들은 돈을 위해 유형을 만들거나 사용하는 것이 "골드 도금"이거나 알려진 요구 사항을 넘어서는 복잡성을 추가한다고 말합니다. 나는 매우 동의하지 않습니다. 개념이 도메인 내에 어디에나있을수록 올바른 추상화를 사용하기 위해 합리적인 노력을 기울여야합니다. 복잡성을보고 싶다면 사용했던 응용 프로그램에서 작업 해보십시오. decimal이제 Currency모든 decimal속성 옆에 추가 속성이 있습니다.

잘못된 추상화를 미리 사용하면 나중에 교체하는 것이 수백 배 더 많은 작업이됩니다. 이는 잠재적으로 기존 코드에 결함이 발생할 수 있음을 의미하며, 가장 중요한 부분은 이러한 결함에 금액, 금전 거래 또는 돈과 관련된 모든 것이 포함될 수 있다는 것입니다.

그리고 십진수 이외의 것을 사용하는 것은 어렵지 않습니다. 구글 "너겟 머니 타입"을 보면 수많은 개발자들이 저를 포함한 추상화를 만들었 음을 알 수 있습니다. DateTime에 날짜를 저장하는 대신 사용 하는 것만 큼 ​​쉽습니다 string.


5

나만의 수업을 만드십시오. 이것은 이상하게 보이지만 .Net 유형은 다른 통화를 다루기에 부적합합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.