È uno sfortunato, penso. Vicino a 139.000, uno Decimal
ha una precisione molto migliore di uno Double
. Tuttavia, a causa di questo problema, abbiamo diversiDouble
s proiettati su lo stessoDecimal
. Ad esempio
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
In realtà ci sono sei diversi rappresentabili Double
valori tradoub1
e doub2
sopra, quindi non sono gli stessi.
Qui è un po 'stupido lavoro-aronud:
static decimal PreciseConvert(double doub)
{
// Handle infinities and NaN-s first (throw exception)
// Otherwise:
return Decimal.Parse(doub.ToString("R"), NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint);
}
La stringa di formato "R"
assicura che le cifre in più sufficienti sono inclusi per rendere l'iniettiva mappatura (nel dominio in cui Decimal
ha precisione superiore).
Si noti che in qualche intervallo, un long
(Int64
) ha una precisione che è superiore a quello di Double
. Quindi ho controllato se le conversioni qui sono fatte nello stesso modo (prima arrotondando a 15 cifre decimali significative). Non sono! Quindi:
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
Sembra incoerente di utilizzare una "regola" diverso quando il bersaglio è decimal
.
Si noti che a causa di ciò, (decimal)(long)doub3
produce un risultato più accurato di appena (decimal)doub3
.
fonte
2012-05-18 21:33:12
possibile duplicato di [La conversione di un numero decimale in doppio in C# produce una differenza] (http://stackoverflow.com/questions/1584314/conversion-of-a-decimal-to-double-number-in- c-results-in-a-difference) –
Well Convert.ToDecimal (somedouble) è esattamente uguale a (decimale) somedouble, quindi non ci sono sorprese. Non sono sicuro del motivo per cui quel cast arrotonda l'ultima cifra verso il basso. – harold
@harold Sei stato ingannato. Fa circolare al più vicino. Il doppio valore termina con 386264 e il decimale con 15 sig fig termina 3863. –