Convertir una variable doble en decimal

96

¿Cómo se lanza un doublea decimalque se usa cuando se hace el desarrollo de la moneda? ¿A dónde Mva?

decimal dtot = (decimal)(doubleTotal);
flo
fuente

Respuestas:

85

Solo usa Mpara un literal numérico, cuando lanza es solo:

decimal dtot = (decimal)doubleTotal;

Tenga en cuenta que un número de punto flotante no es adecuado para mantener un valor exacto, por lo que si primero suma números y luego convierte a Decimal, puede obtener errores de redondeo. Es posible que desee convertir los números Decimalantes de sumarlos, o asegurarse de que los números no sean números de punto flotante en primer lugar.

Guffa
fuente
como pregunta de seguimiento, ¿por qué se necesita la conversión explícita? Lo probé y me sale un error de que un doble no se puede convertir explícitamente en un decimal, pero ¿un decimal no tiene más precisión? (es decir, al igual que la conversión de un int a un doble, puede estar implícita)
4
@Cortana: La precisión de un decimal es mayor, pero el rango es menor. Un valor doble puede estar fuera de rango para un decimal. Ver: stackoverflow.com/questions/7817866/…
Guffa
41

Puede convertir un doble a un decimal como este, sin necesidad del Msufijo literal:

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

Debe usar el Mal declarar un nuevo valor decimal literal:

decimal dec = 123.45M;

(Sin el M, 123.45 se trata como un doble y no se compilará).

Chris Fulstow
fuente
28

use la clase de conversión predeterminada: Convert.ToDecimal(Double)

Timur Sadykov
fuente
1
No porque arrojará una OverflowException double vol_y = (double) Decimal.MaxValue + 10E + 28D; Console.WriteLine ("Convert.ToDecimal (vol_y) =" + Convert.ToDecimal (vol_y));
ToXinE
2
En mi humilde opinión @ToXinE en la mayoría de los casos, un OverflowException es mejor que un silencio que crean datos erróneos
this.myself
16
Convert.ToDecimal(the double you are trying to convert);
Tom
fuente
2
Aprendí que la clase Convert es mucho más flexible y segura que una conversión en C #.
Tom
3
"Seguro"? como cuando no puede emitir, lanza una excepción en tiempo de ejecución en lugar de un error del compilador. Me ha mordido tantas veces que evito activamente Convert ...
Peter Ritchie
8
El hilo de @PeterRitchie es un poco antiguo, pero debería decirse esto: llamar directamente al método Convert sería el enfoque más apropiado. Tal vez solo soy un fanático de la optimización, pero una instrucción menos para resolver es una ventaja (ya que usar la sintaxis de conversión explícita (Tipo) es solo una sobrecarga de operador que llama a Convert).
Mike Johnson
2
@PeterRitchie: Desde una perspectiva de diseño de lenguaje, hubiera sido mejor requerir que un programador usara uno de dos métodos de conversión en lugar de permitir un encasillado de doublea decimal, dado que para un doublevalor como (1000000.0 / 3.0) uno lo haría en algunos casos desea recortar el "exceso" de precisión dando 333333.333333333D, pero en otros casos uno querría retenerlo, dando 333333.333333333313931D. En lugar de simplemente decir "convertir a decimal", el código debe especificar cómo se debe realizar esa conversión.
supercat
2
@supercat, que realmente parece no tener relación con mi primer comentario porque el uso Convert.ToDecimal(double)es el mismo que (decimal)doubleTotal, excepto que si se doubleTotalcambia a un tipo diferente, probablemente evitaría un error en tiempo de compilación e introduciría un error en tiempo de ejecución más difícil de encontrar debido a un ToDecimal diferente se podría llamar a override. El operador de reparto es mucho más explícito ...
Peter Ritchie
1

Bueno, esta es una pregunta antigua y de hecho hice uso de algunas de las respuestas que se muestran aquí. Sin embargo, en mi escenario particular, era posible que el doublevalor al que quería convertir a decimalmenudo fuera mayor que decimal.MaxValue. Entonces, en lugar de manejar excepciones, escribí este método de extensión:

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

El enfoque anterior funciona si no quiere molestarse en manejar las excepciones de desbordamiento y si tal cosa sucede, solo desea mantener el valor máximo posible (mi caso), pero soy consciente de que para muchos otros escenarios este no sería el comportamiento esperado y puede ser la excepción será necesaria la manipulación.

taquion
fuente
1
Esto fallaría en el siguiente caso double _double = (double) decimal.MaxValue; Sugeriría usar> = en la comparación pública estática decimal ToDecimal (este doble _double) => _double> = (doble) decimal.MaxValue? decimal.MaxValue: (decimal) _double;
Martin Eyles