Trasmetti una variabile doppia a Decimal


94

Come si fa a lanciare un doublea decimalche viene utilizzato quando si fa sviluppo valutario. Dove Mva?

decimal dtot = (decimal)(doubleTotal);

Risposte:


83

Usi solo il Mper un letterale numerico, quando lanci è solo:

decimal dtot = (decimal)doubleTotal;

Nota che un numero in virgola mobile non è adatto per mantenere un valore esatto, quindi se aggiungi prima i numeri e poi li converti Decimalpotresti ottenere errori di arrotondamento. Potresti voler convertire i numeri in Decimalprima di sommarli o assicurarti che i numeri non siano numeri in virgola mobile in primo luogo.


come domanda successiva, perché è necessaria la conversione esplicita? L'ho provato e ottengo un errore che un double non può essere cast esplicitamente in un decimale, ma un decimal non ha una maggiore precisione? (Ad esempio, un casting da int a double può essere implicito.)

4
@ Cortana: la precisione di un decimale è maggiore, ma l'intervallo è inferiore. Un valore double potrebbe essere fuori intervallo per un decimale. Vedi: stackoverflow.com/questions/7817866/...
Guffa

40

Puoi lanciare un doppio in un decimale come questo, senza bisogno del Msuffisso letterale:

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

È necessario utilizzare Mquando si dichiara un nuovo valore decimale letterale:

decimal dec = 123.45M;

(Senza il M, 123.45 viene considerato come un doppio e non verrà compilato.)


28

usa la classe di conversione predefinita: Convert.ToDecimal(Double)


1
No perché genererà un'eccezione OverflowException double vol_y = (double) Decimal.MaxValue + 10E + 28D; Console.WriteLine ("Convert.ToDecimal (vol_y) =" + Convert.ToDecimal (vol_y));
ToXinE

2
@ToXinE IMHO nella maggior parte dei casi un'eccezione OverflowException è meglio di una creazione silenziosa di dati errati
this.myself

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

2
Ho imparato che la classe Convert è molto più flessibile e sicura di un cast in C #.
Tom

3
"Sicuro"? come quando non può lanciare, genera un'eccezione in fase di esecuzione invece di un errore del compilatore? Sono stato morso così tante volte che evito attivamente Convert ...
Peter Ritchie,

8
Il thread @PeterRitchie è un po 'vecchio ma va detto: chiamare direttamente il metodo Convert sarebbe l'approccio più appropriato. Forse sono solo un maniaco dell'ottimizzazione, ma un'istruzione in meno da risolvere è un bonus (poiché l'uso della sintassi cast esplicita (Type) è solo un sovraccarico di operatori che chiama Convert).
Mike Johnson

1
@PeterRitchie: dal punto di vista del design del linguaggio, sarebbe stato meglio richiedere a un programmatore di utilizzare uno dei due metodi di conversione piuttosto che consentire un typecast da doublea decimal, dato che per un doublevalore come (1000000.0 / 3.0) si sarebbe in alcuni casi si desidera ritagliare la precisione "in eccesso" ottenendo 333333.333333333D, ma in altri casi si vorrebbe mantenerla, ottenendo 333333.333333333313931D. Invece di dire semplicemente "converti in decimale", il codice dovrebbe specificare come deve essere eseguita la conversione.
supercat

2
@supercat che sembra davvero non correlato al mio primo commento perché l'uso Convert.ToDecimal(double)è lo stesso di (decimal)doubleTotal, tranne se doubleTotalcambiato in un tipo diverso probabilmente eviterai un errore in fase di compilazione e introdurrai un errore di runtime più difficile da trovare perché un ToDecimal diverso override potrebbe essere chiamato. L'operatore del cast è molto più esplicito ...
Peter Ritchie

1

Bene, questa è una vecchia domanda e ho effettivamente utilizzato alcune delle risposte mostrate qui. Tuttavia, nel mio particolare scenario era possibile che il doublevalore a cui volevo convertirmi decimalfosse spesso maggiore di decimal.MaxValue. Quindi, invece di gestire le eccezioni, ho scritto questo metodo di estensione:

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

L'approccio di cui sopra funziona se non vuoi preoccuparti di gestire le eccezioni di overflow e se accade una cosa del genere vuoi solo mantenere il valore massimo possibile (il mio caso), ma sono consapevole che per molti altri scenari questo non sarebbe il comportamento previsto e potrebbe essere necessaria la gestione delle eccezioni.


1
Ciò non andrebbe a buon fine nel seguente caso double _double = (double) decimal.MaxValue; Suggerirei di utilizzare> = nel confronto decimale statico pubblico ToDecimal (questo double _double) => _double> = (double) decimal.MaxValue? decimal.MaxValue: (decimal) _double;
Martin Eyles
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.