二重変数を10進数にキャストする


94

通貨開発を行うときに使用されるa doubleをどのようにキャストしますかdecimal。どこにM行くの?

decimal dtot = (decimal)(doubleTotal);

回答:


83

M数値リテラルにのみ使用します。キャストするときは次のとおりです。

decimal dtot = (decimal)doubleTotal;

浮動小数点数は正確な値を維持するのに適していないため、最初に数値を加算してから変換すると、Decimal丸めエラーが発生する可能性があることに注意してください。数値をDecimal加算する前にに変換するか、最初に数値が浮動小数点数でないことを確認してください。


フォローアップの質問として、なぜ明示的な変換が必要なのですか?試してみましたが、doubleを明示的にdecimalにキャストできないというエラーが表示されますが、decimalの方が精度が高くないのですか?(つまり、intからdoubleへのキャストは暗黙的に行うことができます。)

4
@Cortana:小数の精度は高くなりますが、範囲は狭くなります。double値は、10進数の範囲外である可能性があります。参照:stackoverflow.com/questions/7817866/...
Guffa

40

次のようにdoubleをdecimalにキャストできますが、Mリテラルサフィックスは必要ありません。

double dbl = 1.2345D;
decimal dec = (decimal) dbl;

M新しいリテラル10進値を宣言する場合は、を使用する必要があります。

decimal dec = 123.45M;

(なし M、123.45はdoubleとして扱われ、コンパイルされません。)


28

デフォルトの変換クラスを使用: Convert.ToDecimal(Double)


1
いいえ、OverflowExceptionをスローするためです。vol_y=(double)Decimal.MaxValue + 10E + 28D; Console.WriteLine( "Convert.ToDecimal(vol_y)=" + Convert.ToDecimal(vol_y));
ToXinE 14

2
@ToXinE IMHOほとんどの場合、OverflowExceptionは暗黙的に間違ったデータを作成するよりも優れています
this.myself

16
Convert.ToDecimal(the double you are trying to convert);

2
ConvertクラスはC#のキャストよりもはるかに柔軟で安全であることを学びました。
トム

3
"安全"?キャストできないときのように、コンパイラエラーの代わりに実行時に例外をスローしますか?何度も噛まれたことで、積極的にConvertを避けています...
Peter Ritchie

8
@PeterRitchieスレッドは少し古いですが、これは言う必要があります:Convertメソッドを直接呼び出す方が適切なアプローチです。たぶん私は単なる最適化フリークですが、解決するための1つの少ない命令はボーナスです(明示的な(Type)キャスト構文を使用すると、Convertを呼び出す演算子のオーバーロードになるためです)。
マイクジョンソン

1
@PeterRitchie:言語設計の観点から、(1000000.0 / 3.0)のような値の場合、場合によってはタイプキャストをdoubletoに許可するのではなく、プログラマーに2つの変換方法のいずれかを使用するように要求する方が良いでしょう「過剰な」精度をクリップして333333.333333333Dを生成したいが、他の場合では、それを保持して333333.333333333313931Dを生成することもできます。コードは、単に「10進数に変換する」と言うのではなく、変換を実行する方法を指定する必要があります。decimaldouble
スーパーキャット2014年

2
@supercat Convert.ToDecimal(double)は、使用がと同じであるため、最初のコメントとは実際には無関係のようですが、別のタイプに変更された(decimal)doubleTotal場合doubleTotalは、コンパイル時エラーを回避し、ToDecimal が異なるために見つけにくいランタイムエラーが発生する可能性がありますオーバーライドが呼び出される可能性があります。キャスト演算子の方がはるかに明確です...
Peter Ritchie

1

さて、これは古い質問であり、私は実際にここに示されている回答のいくつかを利用しました。それにもかかわらず、私の特定のシナリオではdouble、変換したい値decimalがより大きいことがよくありましたdecimal.MaxValue。したがって、例外を処理する代わりに、この拡張メソッドを作成しました。

    public static decimal ToDecimal(this double @double) => 
        @double > (double) decimal.MaxValue ? decimal.MaxValue : (decimal) @double;

上記のアプローチは、オーバーフロー例外の処理に煩わされたくない場合、およびそのような事態が発生した場合に、可能な最大値(私の場合)を保持したい場合に機能しますが、他の多くのシナリオでは、これは期待される動作ではないことを認識しています例外処理が必要になる可能性があります。


1
これは、次の場合に失敗します。double _double =(double)decimal.MaxValue; 比較で> =を使用することをお勧めしますpublic static decimal ToDecimal(this double _double)=> _double> =(double)decimal.MaxValue?decimal.MaxValue:(10進数)_double;
Martin Eyles、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.