web-dev-qa-db-ja.com

C#オブジェクトを10進数に変換

値が0.39999999999999997のオブジェクトを、精度を失うことなく10進変数に変換しようとしています。

object d = 0.39999999999999997;

私は以下の方法を試しました。

decimal val1 = Convert.ToDecimal(d); // val1 = 0.4
object val2 = Convert.ChangeType(d, Type.GetType("System.Decimal")); // val2 = 0.4
decimal val3 = decimal.Parse(d.ToString()); // val3 = 0.4
decimal val4 = (Decimal) d; // val4 = 0.4

以下に示すように、これは10進データ型がこの値を格納できないという問題ではないことを私は知っています。

decimal val5 = 0.39999999999999997m; // val5 = 0.39999999999999997;

精度を失うことなく、このオブジェクトを10進数に変換するにはどうすればよいですか?

それが問題になる場合は、.NET Framework3.5を使用しています。

14
Chathura W

私はこれがあなたが探しているコードだと思います:

object d = 0.39999999999999997;
//Unbox value
double doubleVal = (double)d;

//Convert to string. R format specifier gives a string that can round-trip to an identical number.  
//Without R ToString() result would be doubleAsString = "0.4"
string doubleAsString = doubleVal.ToString("R"); 

//Now that you have doubleAsString = "0.39999999999999997" parse it!
decimal decimalVal = decimal.Parse(doubleAsString);
10
Reniuz

これを機能させるには、同様に割り当てる必要があります

_object d = 0.39999999999999997M;
_

強制しない限り、オブジェクトが精度を維持する方法はありません。 (これが実際のコードでない場合は、割り当てられた方法として表示する必要があります)

そうして初めて、このようなものが機能しますdecimal dec = Convert.ToDecimal(d);

4
V4Vendetta

データベースからデータを読み取っているとき(コメントの1つで指摘したように、IMOは質問にそれを追加する必要があります)、データベースからの読み取り中に2倍に変換して元に戻すことを許可するのはひどい考えだと思います。精度が失われるからです。 [固定小数点として、または小数を表すことができる記数法で格納される可能性があります]。保存された値を10進数として直接読み取る(スキーマなどを編集する)か、それが不可能な場合は文字列として読み取り、Decimal.Parse()を使用して実際の値を取得する必要があると思います。

実際、あなたの数0.39999999999999997は小数点以下17桁であるため、doubleとして安全に保存することはできません。

P.S. JonSkeetによって書かれた.netDoublesと丸めに関する すばらしい記事 があります。

1
Boris Treukhov

真剣にあなたがしなければならないのはこのようなものです...

object d = 0.39999999999999997; 
decimal result;
decimal.TryParse(d.ToString(), out result);
return result;
0
Ben Brown
string val = "0.39999999999999997");
decimal d = decimal.Parse(val,
    System.Globalization.NumberStyles.AllowDecimalPoint);//0.39999999999999997
0
Jalal Said

Decimal d = new Decimal(d);

dがdoubleの場合、ドキュメントによると [〜#〜] msdn [〜#〜] これにより精度が維持されます。

このコンストラクターは、最も近い値への丸めを使用して、値を有効数字15桁に丸めます。これは、数値が15桁を超え、有効桁数がゼロの場合でも実行されます。

0
Spence

このページで http://msdn.Microsoft.com/en-us/library/364x0z75(v = vs.80).aspx 「接尾辞mがないと、番号はダブル"
そしてこのコード

object o = 0.39999999999999997;
Console.WriteLine(o.GetType());

現れます System.Double

これは

object o = 0.39999999999999997m;
Console.WriteLine(o.GetType());

現れます System.Decimal
つまり、接尾辞mがないと精度が失われます。

0
PierrOz

オブジェクトd = 0.399999999999999999999999997M;あなたが働くだろう。

0
Deepansh Gupta