Convertir decimal a doble

672

Quiero usar a Track-Barpara cambiar Formla opacidad de a.

Este es mi código:

decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;

Cuando construyo la aplicación, aparece el siguiente error:

No se puede convertir implícitamente el tipo decimaladouble

He intentado usar transy doublepero luego Controlno funciona. Este código funcionó bien en un proyecto anterior de VB.NET.

Huevos McLaren
fuente
11
Además, Decimal no puede representar un valor tan amplio como un Doble. Decimal solo puede subir hasta +/- 7.9228162514264337593543950335E + 28; mientras que un Double puede subir hasta +/- 1.79769313486232E + 308
TraumaPony
8
Alguien debería marcar este como un duplicado.
Ivan
8
@Ivan: Esta es la cuarta pregunta que se hace en SO ...
Nikolas
1
@ Nikolas: De hecho. Rastreado aquí hoy.
junio

Respuestas:

447

No doublees necesario un reparto explícito como este:

double trans = (double) trackBar1.Value / 5000.0;

Identificar la constante como 5000.0(o como 5000d) es suficiente:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
Kevin Dente
fuente
123

Una respuesta más genérica para la pregunta genérica "¿Decimal vs doble?": Decimal para cálculos monetarios para preservar la precisión, doble para cálculos científicos que no se ven afectados por pequeñas diferencias. Dado que Double es un tipo nativo de la CPU (la representación interna se almacena en la base 2 ), los cálculos realizados con Double funcionan mejor que Decimal (que se representa en la base 10 internamente).

huseyint
fuente
83

Su código funcionó bien en VB.NET porque implícitamente realiza cualquier conversión, mientras que C # tiene tanto implícitos como explícitos.

En C #, la conversión de decimal a doble es explícita a medida que pierde precisión. Por ejemplo, 1.1 no puede expresarse con precisión como un doble, pero puede expresarse como un decimal (consulte " Números de coma flotante, más inexactos de lo que cree ", por la razón).

En VB, el compilador agregó la conversión para usted:

decimal trans = trackBar1.Value / 5000m;
this.Opacity = (double) trans;

Eso (double)tiene que establecerse explícitamente en C #, pero puede estar implícito en el compilador más "tolerante" de VB.

Keith
fuente
80

¿Por qué estás dividiendo entre 5000? Simplemente configure los valores Mínimo y Máximo de TrackBar entre 0 y 100 y luego divida el Valor por 100 para el porcentaje de Opacidad. El mínimo de 20 ejemplos a continuación evita que el formulario se vuelva completamente invisible:

private void Form1_Load(object sender, System.EventArgs e)
{
    TrackBar1.Minimum = 20;
    TrackBar1.Maximum = 100;

    TrackBar1.LargeChange = 10;
    TrackBar1.SmallChange = 1;
    TrackBar1.TickFrequency = 5;
}

private void TrackBar1_Scroll(object sender, System.EventArgs e)
{
    this.Opacity = TrackBar1.Value / 100;
}
Gordon Bell
fuente
55
¿No sería esto simplemente mover el problema? En lugar de un problema con 5000, OP tendría un problema con 100?
jww
62

Tienes dos problemas Primero, Opacityrequiere un valor doble, no decimal. El compilador le dice que si bien hay una conversión entre decimal y doble, es una conversión explícita que debe especificar para que funcione. El segundo es que TrackBar.Valuees un valor entero y dividir un int por un int da como resultado un int sin importar a qué tipo de variable se lo asigne. En este caso, hay una conversión implícita de int a decimal o doble, porque no hay pérdida de precisión cuando realiza la conversión, por lo que el compilador no se queja, pero el valor que obtiene siempre es 0, presumiblemente, ya quetrackBar.Valuesiempre es inferior a 5000. La solución es cambiar su código para usar double (el tipo nativo de Opacity) y hacer aritmética de coma flotante al hacer explícitamente la constante doble, lo que tendrá el efecto de promover la aritmética, o convertir trackBar.Valuea double , que hará lo mismo, o ambos. Ah, y no necesita la variable intermedia a menos que se use en otro lugar. Supongo que el compilador lo optimizaría de todos modos.

trackBar.Opacity = (double)trackBar.Value / 5000.0;
tvanfosson
fuente
58

En mi opinión, es deseable ser lo más explícito posible. Esto agrega claridad al código y ayuda a sus compañeros programadores que eventualmente pueden leerlo.

Además de (o en lugar de) agregar un .0al número, puede usar decimal.ToDouble().

Aquí hay unos ejemplos:

// Example 1
double transperancy = trackBar1.Value/5000;
this.Opacity = decimal.ToDouble(transperancy);

// Example 2 - with inline temp
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
andnil
fuente
57

Parece que this.Opacityes un valor doble, y al compilador no le gusta que intentes meter un valor decimal en él.

Ryan Fox
fuente
50

La propiedad Opacity es de doble tipo:

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

o simplemente:

this.Opacity = trackBar1.Value / 5000.0;

o:

this.Opacity = trackBar1.Value / 5000d;

Tenga en cuenta que estoy usando 5000.0(o 5000d) para forzar una división doble porque trackBar1.Valuees un número entero y realizaría una división entera y el resultado sería un número entero.

Darin Dimitrov
fuente
49

Deberías usar en 5000.0lugar de 5000.

Dinah
fuente
47

Suponiendo que está usando WinForms, Form.Opacityes de tipo double, por lo que debe usar:

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

A menos que necesite el valor en otro lugar, es más simple escribir:

this.Opacity = trackBar1.Value / 5000.0;

La razón por la que el control no funciona cuando cambiaste tu código para que sea simplemente doble fue porque tenías:

double trans = trackbar1.Value / 5000;

que interpretó el 5000como un entero, y debido a trackbar1.Valueque también es un entero, su transvalor siempre fue cero. Al hacer explícitamente el valor numérico de coma flotante al agregar el .0compilador, ahora puede interpretarlo como un doble y realizar el cálculo adecuado.

ChrisF
fuente
41

La mejor solución es:

this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
Danny Fox
fuente
41

Como Opacityes un valor doble, solo usaría un doble desde el principio y no lanzaría en absoluto, pero asegúrese de usar un doble al dividir para que no pierda ninguna precisión

Opacity = trackBar1.Value / 5000.0;
Darryl
fuente
36
this.Opacity = trackBar1.Value / 5000d;
Kolappan N
fuente
0

Prueba esto:

Opacity = decimal.ToDouble(trackBar1.Value / 5000.0);```
usuario12828597
fuente