C#でお金を稼ぐのに最適なデータ型は何ですか?


426

C#でお金を稼ぐのに最適なデータ型は何ですか?


4
この投稿からの回答が役立つ場合があります。
ntombela 2009年

ここでは、すべてのデータ型のマッピングです: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

10進数では次のように記述されています

decimalキーワードは、128ビットのデータ型を示します。浮動小数点型と比較して、10進数型は精度が高く範囲が狭いため、財務 計算や通貨計算に適しています。

次のように小数を使用できます。

decimal myMoney = 300.5m;

41
そのリンクについて重要なことを説明する必要があります。回答はそれ自体で十分であり、追加の参照または詳細としてのリンクがあります。stackoverflow.com/help/how-to-answer
TheRubberDuckを

2
したがって、最小長の回答は、最小長のコメントよりも文字数が少なくなる可能性があります-興味深いです!私が簡潔で簡潔な答えに問題があるわけではありません。特に、それがさらに深い議論にリンクしているという点で「深い」場合は特にそうです。
B.クレイシャノン

3
すばらしい答えです。質問に完全に答えるため、これ以上の説明は必要ないと思います。MSDNドキュメントへのリンクは、私にとってはおまけです。ブラボー!
trnelson 2016年

@Leee Treveil、お金はどのようなもの(9.0098)はポイントの後ろの4文字を意味します
SAR

114

System.Decimal

Decimal値タイプは、正の79,228,162,514,264,337,593,543,950,335から負の79,228,162,514,264,337,593,543,950,335までの範囲の10進数を表します。Decimal値タイプは、多数の有効な整数および小数桁を必要とし、丸め誤差がない財務計算に適しています。Decimalタイプは、丸めの必要性を排除しません。むしろ、丸めによるエラーを最小限に抑えます。

なぜdoubleが使用されるべきではないのかについて、zneakによるこの素晴らしい答えを指摘したいと思います。


68

エンタープライズアプリケーションアーキテクチャのパターンMoneyパターンを使用します。10進数として金額を指定し、enumとして通貨を指定します。


2
私は実際にこれを提案するつもりでしたが、通貨をクラスにして、為替レートを定義できるようにします(「基本通貨」、多くの場合、米ドル(為替レートは1.00に設定)に関連して)。
Thomas Owens

5
このスレッドの将来の訪問者(私のように)には、今これがあります:nuget.org/packages/Moneyとそれは素晴らしいです!
Korijn 2014年

そのような型が構造体かクラスかどうか疑問に思っています。10進数+(int)列挙型は20バイトになります。私のお金はまだ残っています。
nawfal 16

そのMoneynugetにはプロジェクトサイトへの無効なgithubリンクがあるので、ドキュメントはありませんか?
ジョージ・マウアー

これに関する問題は、独自の実装を作成する場合、実際にそれを永続化する方法を理解する必要があることです。また、最も一般的なORM(EF)は、カスタムデータ型をまったくサポートしていません。したがって、誰かが取得するように要求されて、本当に非常に簡単なものでなければなりません何をするために雑草に深いです。
ジョージマウアー

25

10進数。doubleを選択した場合、丸め誤差を受け入れることになります。


8
@Jess doubleは、浮動小数点がすべての数値を正確に表すことができないため、丸めエラーを引き起こす可能性があります(たとえば、0.01は浮動小数点で正確に表現されません)。Decimal一方、正確に数値を表します。(トレードオフはDecimal浮動小数点よりも範囲が狭いです)浮動小数点は*不注意な*丸め誤差(例えば0.01+0.01 != 0.02)を与える可能性があります。Decimal丸めエラーが発生する可能性がありますが、要求した場合のみ(たとえば、Math.Round(0.01+0.02)ゼロを返す)
Ian Boyd

2
@IanBoyd:値「$ 1.57」は正確に表すことができます(double)157。doubleスケーリングとドメイン固有の丸めを適切に使用して慎重に適用すると、完全に正確になります。丸めがずさんな場合、decimal意味的に正しくない結果が生じる可能性があります(たとえば、最も近いペニーに丸められるはずの複数の値を加算したが、実際には最初にそれらの周りにない場合)。唯一の良い点decimalは、スケーリングが組み込まれていることです。
スーパーキャット2012年

1
@supercat、このコメントに関して「最も近いペニーに丸められるはずの複数の値を足し合わせても、実際には最初にそれらを囲んでいない場合」、フロートがこれをどのように解決するかわかりません。これはユーザーエラーで、小数部のIMHOとは関係ありません。私はポイントを取得しますが、主にIanBoydがそれを指定したためです...
sawe 2013


13

Moneyパターンに同意する:小数を使用する場合、通貨の扱いが面倒です。

Currencyクラスを作成すると、正しいToString()メソッド、解析値のより詳細な制御、除算のより適切な制御など、お金に関連するすべてのロジックをそこに配置できます。

また、Currencyクラスを使用すると、他のデータと誤ってお金を混同する可能性はありません。


10

別のオプション(特に、独自のクラスをロールしている場合)は、intまたはint64を使用して、下4桁(または場合によっては2)を「小数点の右側」として指定することです。したがって、「端」では、途中で「* 10000」、そして途中で「/ 10000」が必要になります。これは、MicrosoftのSQL Serverで使用されるストレージメカニズムです。。http://msdn.microsoft.com/en-au/library/ms179882.aspxをください

これの素晴らしさは、すべての合計が(高速)整数演算を使用して実行できることです。


7

私が使用decimalしてきたほとんどのアプリケーションは、お金を表すために使用しました。これは、アプリケーションが複数の通貨に関係することは決してないという想定に基づいています。

この仮定は、アプリケーションが通貨の異なる他の国では使用されないという別の仮定に基づいている場合があります。それが誤りであることが判明した事例を見たことがあります。

今、仮定は新しい方法で挑戦されています:ビットコインなどの新しい通貨はより一般的になり、それらはどの国にも固有ではありません。1つの国でのみ使用されるアプリケーションが複数の通貨をサポートする必要がある場合があることは非現実的ではありません。

一部の人々は、お金のためだけにタイプを作成または使用することも「金メッキ」である、または既知の要件を超える複雑さを追加すると言います。私は強く反対します。ドメイン内の概念がユビキタスであるほど、正しい抽象化を前もって使用するための合理的な努力をすることがより重要です。複雑さを確認したい場合は、以前は使用していたアプリケーションで作業してみてください。すべてのプロパティの横にdecimal追加のCurrencyプロパティがありdecimalます。

間違った抽象化を最初に使用すると、後でそれを置き換えるのに100倍の手間がかかります。つまり、既存のコードに欠陥が潜在的に導入されることを意味します。最良の部分は、これらの欠陥には、金額、金額を伴うトランザクション、または金額を伴うあらゆるものが含まれる可能性が高いことです。

そして、10進数以外のものを使用することはそれほど難しくありません。グーグルは「お金を稼ぐタイプ」であり、多数の開発者がそのような抽象化を作成していることがわかります(私を含めて)。それは簡単です。DateTime日付をに保存する代わりに、を使用するのと同じくらい簡単stringです。


5

独自のクラスを作成します。これは奇妙に思えますが、.Netタイプは異なる通貨をカバーするには不十分です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.