Convertir Decimal a Doble?


Quiero usar una barra de seguimiento para cambiar la opacidad de un formulario.

Este es mi código:

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

Cuando compilo la aplicación, da el siguiente error:

No puede convertir implícitamente el tipo 'decimal' a 'double'.

He intentado usar trans y double pero entonces el control no funciona. Este código funcionó bien en un pasado VB.NET proyecto.

Author: Eggs McLaren, 2008-08-01

13 answers

Un cast explícito para doblar así no es necesario:

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;
 401
Author: Kevin Dente,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-16 05:06:57

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

 117
Author: huseyint,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-11 14:42:28

Su código funcionó bien en VB.NET porque implícitamente hace cualquier molde, mientras que C# tiene ambos implícitos y explícitos.

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

En VB la conversión fue añadida por el compilador:

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

Que (double) tiene que ser explícitamente indicado en C#, pero puede ser implícito por el compilador más 'indulgente' de VB.

 76
Author: Keith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-14 11:51:08

¿Por qué estás dividiendo por 5000? Simplemente establezca los valores Mínimo y Máximo de la barra de seguimiento entre 0 y 100 y luego divida el Valor entre 100 para el porcentaje de opacidad. El ejemplo mínimo de 20 a continuación evita que la forma 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;
}
 74
Author: Gordon Bell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-01 12:51:15

Tienes dos problemas. Primero, Opacity requiere un doble, no un valor decimal. El compilador le dice que si bien hay una conversión entre decimal y doble, es una conversión explícita que necesita especificar para que funcione. La segunda es que TrackBar.Value es un valor entero y dividir un int por un int resulta en un int sin importar a qué tipo de variable lo asigne. En este caso hay un molde implícito de int a decimal o doble-porque no hay pérdida de precisión al hacer el cast - por lo que el compilador no se queja, pero el valor que obtiene es siempre 0, presumiblemente, ya que trackBar.Value es siempre menor que 5000. La solución es cambiar su código para usar double (el tipo nativo para Opacidad) y hacer aritmética de coma flotante haciendo explícitamente la constante un double - que tendrá el efecto de promover la aritmética - o casting trackBar.Value a double, que hará lo mismo - o ambos. Oh, y usted no necesita la variable intermedia a menos que usado en otra parte. Mi conjetura es que el compilador lo optimizaría, de todos modos.

trackBar.Opacity = (double)trackBar.Value / 5000.0;
 57
Author: tvanfosson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-22 16:40:13

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

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

Aquí hay algunos 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);
 55
Author: andnil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-14 11:52:15

Suena como this.Opacity es un valor doble, y al compilador no le gusta que intentes meter un valor decimal en él.

 54
Author: Ryan Fox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-14 11:54:40

Debe usar 5000.0 en lugar de 5000.

 45
Author: Dinah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-14 11:54:23

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;

Observe que estoy usando 5000.0 (o 5000d) para forzar una división doble porque trackBar1.Value es un entero y realizaría una división entera y el resultado sería un entero.

 44
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-31 19:08:26

Asumiendo que está usando WinForms, Form.Opacity es 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 sencillo 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 un double fue porque tenías:

double trans = trackbar1.Value / 5000;

Que interpretó el 5000 como un entero, por lo que su valor trans siempre fue cero. Al hacer explícitamente el numérico un valor de coma flotante agregando el .0 el compilador ahora puede interpretarlo como un doble y realizar el cálculo adecuado.

 42
Author: ChrisF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-05 16:19:19

La mejor solución es:

this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
 38
Author: Danny Fox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-06 08:07:53

Dado que Opacity es 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;
 37
Author: Darryl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-14 11:55:08
this.Opacity = trackBar1.Value / 5000d;
 32
Author: AkoSi Asiong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-20 17:18:47