二重の_"138630.78380386264"
_があり、それを10進数に変換したいのですが、その場合は、キャストまたはConvert.ToDecimal()
を使用して行い、精度を失います。
どうしたの? 10進数とdoubleの両方がこの数値を保持できます。
_double doub = double.Parse("138630.78380386264");
decimal dec = decimal.Parse("138630.78380386264");
string decs = dec.ToString("F17");
string doubse =DoubleConverter.ToExactString(doub);
string doubs = doub.ToString("F17");
decimal decC = (decimal) doub;
string doudeccs = decC.ToString("F17");
decimal decConv = Convert.ToDecimal(doub);
string doudecs = decConv.ToString("F17");
_
また:デバッガーが示すのと同じ結果を出力するためにToString()
をdoubleで取得するにはどうすればよいですか?例えば_138630.78380386264
_?
_138630.78380386264
_は、倍精度で正確に表現できません。最も近い倍精度数(見つかった here )は_138630.783803862635977566242218017578125
_であり、これは調査結果と一致します。
10進数への変換に精度が含まれない理由を尋ねます。 Convert.ToDecimal()
のドキュメントには答えがあります:
このメソッドから返されるDecimal値には、最大15桁の有効数字が含まれています。 valueパラメータに15桁を超える有効数字が含まれている場合は、最も近い値に丸めることで丸められます。次の例は、Convert.ToDecimal(Double)メソッドが最も近い値に丸めることで、有効数字15桁のDecimal値を返す方法を示しています。
15の有効数字で最も近い値に四捨五入されたdouble値は、上記のとおり正確に_138630.783803863
_です。
残念なことだと思います。 139,000近くでは、Decimal
はDouble
よりもはるかに精度が高くなります。しかし、それでも、この問題のためにdifferentDouble
sが同じDecimal
に投影されています。例えば
double doub1 = 138630.7838038626;
double doub2 = 138630.7838038628;
Console.WriteLine(doub1 < doub2); // true, values differ as doubles
Console.WriteLine((decimal)doub1 < (decimal)doub2); // false, values projected onto same decimal
実際には、上記のsix表現可能なDouble
値betweendoub1
とdoub2
があるため、同じではありません。
これはいくぶんばかげた作業論です:
static decimal PreciseConvert(double doub)
{
// Handle infinities and NaN-s first (throw exception)
// Otherwise:
return Decimal.Parse(doub.ToString("R"), NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint);
}
"R"
フォーマット文字列は、マッピングを単射的にするのに十分な追加の数字が含まれることを保証します(Decimal
が優れた精度を持つドメインで)。
一部の範囲では、long
(Int64
)の精度がDouble
よりも高いことに注意してください。そこで、ここでの変換が同じ方法で行われるかどうかを確認しました(最初の小数点以下15桁に丸め)。ではない!そう:
double doub3 = 1.386307838038626e18;
double doub4 = 1.386307838038628e18;
Console.WriteLine(doub3 < doub4); // true, values differ as doubles
Console.WriteLine((long)doub3 < (long)doub4); // true, full precision of double used when converting to long
ターゲットがdecimal
の場合、別の「ルール」を使用することに一貫性がないようです。
このため、(decimal)(long)doub3
は(decimal)doub3
よりも正確な結果を生成することに注意してください。