W jaki sposób można rzucić double
na decimal
który jest używany podczas opracowywania waluty. Gdzie to M
idzie?
decimal dtot = (decimal)(doubleTotal);
Odpowiedzi:
Używasz tylko M
dla literału numerycznego, kiedy przesyłasz to tylko:
decimal dtot = (decimal)doubleTotal;
Zauważ, że liczba zmiennoprzecinkowa nie nadaje się do przechowywania dokładnej wartości, więc jeśli najpierw dodasz liczby do siebie, a następnie przekonwertujesz na Decimal
, możesz uzyskać błędy zaokrągleń. Możesz chcieć przekonwertować liczby na Decimal
przed dodaniem ich do siebie lub upewnić się, że liczby nie są liczbami zmiennoprzecinkowymi w pierwszej kolejności.
Możesz rzucić podwójną na dziesiętną w ten sposób, bez potrzeby M
dosłownego sufiksu:
double dbl = 1.2345D;
decimal dec = (decimal) dbl;
Powinieneś użyć M
przy deklarowaniu nowej dosłownej wartości dziesiętnej:
decimal dec = 123.45M;
(Bez M
123.45 jest traktowane jako podwójne i nie zostanie skompilowane).
użyj domyślnej klasy konwersji: Convert.ToDecimal(Double)
Convert.ToDecimal(the double you are trying to convert);
double
do decimal
, biorąc pod uwagę, że dla double
wartości takiej jak (1000000.0 / 3.0) w niektórych przypadkach chcą obciąć „nadmiar” precyzji, uzyskując 333333,333333333D, ale w innych przypadkach chcielibyśmy ją zachować, uzyskując 333333,333333333313931D. Zamiast po prostu mówić „przekonwertuj na liczbę dziesiętną”, kod powinien określać sposób wykonania tej konwersji.
Convert.ToDecimal(double)
jest takie samo jak (decimal)doubleTotal
, z wyjątkiem tego, że jeśli zostanie doubleTotal
zmieniony na inny typ, prawdopodobnie unikniesz błędu w czasie kompilacji i wprowadzisz trudniejszy do znalezienia błąd czasu wykonywania, ponieważ inny ToDecimal nadpisanie może zostać wywołane. Operator obsady jest dużo bardziej dosadny ...
Cóż, to stare pytanie i rzeczywiście skorzystałem z niektórych z przedstawionych tutaj odpowiedzi. Niemniej jednak w moim konkretnym scenariuszu było możliwe, że double
wartość, na którą chciałem przeliczyć, decimal
była często większa niż decimal.MaxValue
. Tak więc zamiast obsługiwać wyjątki napisałem tę metodę rozszerzenia:
public static decimal ToDecimal(this double @double) =>
@double > (double) decimal.MaxValue ? decimal.MaxValue : (decimal) @double;
Powyższe podejście działa, jeśli nie chcesz zawracać sobie głowy obsługą wyjątków przepełnienia i jeśli coś takiego się wydarzy, chcesz po prostu zachować maksymalną możliwą wartość (mój przypadek), ale mam świadomość, że w wielu innych scenariuszach nie byłoby to oczekiwane zachowanie i może być potrzebna obsługa wyjątków.