Question Convertir décimal en double?


Je veux utiliser une barre de suivi pour modifier l'opacité d'un formulaire.

C'est mon code:

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

Lorsque je compile l'application, cela donne l'erreur suivante:

Impossible de convertir le type implicitement 'decimal' à 'double'.

J'ai essayé d'utiliser trans et double mais alors le contrôle ne fonctionne pas. Ce code a bien fonctionné dans un projet VB.NET passé.


568
2017-07-31 22:17


origine


Réponses:


Une conversion explicite en double comme ceci n'est pas nécessaire:

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

Identifier la constante comme 5000.0 (ou comme 5000d) est suffisant:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;

401
2017-08-01 14:23



Une réponse plus générique pour la question générique "Decimal vs Double?": Décimal pour des calculs monétaires pour préserver la précision, Double pour les calculs scientifiques qui ne sont pas affectés par de petites différences. Puisque Double est un type natif de la CPU (la représentation interne est stockée dans base 2), les calculs faits avec Double donnent de meilleurs résultats que Decimal (qui est représenté dans base 10 intérieurement).


117
2017-08-10 17:54



Votre code a bien fonctionné dans VB.NET car il fait implicitement des conversions, alors que C # a des implicites et des explicites.

En C #, la conversion de décimale en double est explicite car vous perdez de la précision. Par exemple, 1.1 ne peut pas être exprimé avec précision en tant que double, mais peut être exprimé en décimal (voir "Numéros de virgule flottante - plus inexactes que vous ne le pensez"pour la raison pourquoi).

Dans VB, la conversion a été ajoutée pour vous par le compilateur:

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

Cette (double) doit être explicitement indiqué en C #, mais peut être implicite par le compilateur plus "pardonnant" de VB.


76
2017-09-21 03:51



Pourquoi divisez-vous par 5000? Réglez simplement les valeurs minimum et maximum de TrackBar entre 0 et 100, puis divisez la valeur par 100 pour le pourcentage d'opacité. L'exemple 20 ci-dessous empêche le formulaire de devenir complètement 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
2018-02-27 11:45



Vous avez deux problèmes. Premier, Opacity nécessite un double, pas une valeur décimale. Le compilateur vous indique que bien qu'il y ait une conversion entre décimal et double, il s'agit d'une conversion explicite que vous devez spécifier pour que cela fonctionne. Le deuxième est que TrackBar.Value est une valeur entière et la division d'un int par un int aboutit à un int quel que soit le type de variable que vous lui attribuez. Dans ce cas, il y a une distribution implicite de int en décimal ou double - parce qu'il n'y a pas de perte de précision quand vous faites le cast - donc le compilateur ne se plaint pas, mais la valeur que vous obtenez est toujours 0, sans doute trackBar.Value est toujours inférieur à 5000. La solution est de changer votre code pour utiliser double (le type natif pour Opacity) et faire l'arithmétique à virgule flottante en faisant explicitement de la constante un double - ce qui aura pour effet de promouvoir l'arithmétique - ou de lancer trackBar.Value doubler, ce qui fera la même chose - ou les deux. Oh, et vous n'avez pas besoin de la variable intermédiaire sauf si elle est utilisée ailleurs. Ma conjecture est que le compilateur l'optimiserait de toute façon.

trackBar.Opacity = (double)trackBar.Value / 5000.0;

57
2017-08-05 20:18



À mon avis, il est souhaitable d'être aussi explicite que possible. Cela ajoute de la clarté au code et aide vos collègues programmeurs qui pourraient éventuellement le lire.

En plus de (ou au lieu de) ajouter un .0 au numéro, vous pouvez utiliser decimal.ToDouble().

Voici quelques exemples:

// 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
2017-08-01 13:53



Cela ressemble this.Opacity est une double valeur, et le compilateur n'aime pas que vous essayiez d'entasser une valeur décimale dedans.


54
2017-11-20 14:36



Tu devrais utiliser 5000.0 au lieu de 5000.


45
2017-08-31 19:08



le Opacité la propriété est de type double:

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

ou simplement:

this.Opacity = trackBar1.Value / 5000.0;

ou:

this.Opacity = trackBar1.Value / 5000d;

Notez que j'utilise 5000.0 (ou 5000d) forcer une double division parce que trackBar1.Value est un nombre entier et il effectuerait une division entière et le résultat serait un entier.


44
2017-08-31 19:09



En supposant que vous utilisez WinForms, Form.Opacity est de type double, vous devriez donc utiliser:

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

Sauf si vous avez besoin de la valeur ailleurs, il est plus simple d'écrire:

this.Opacity = trackBar1.Value / 5000.0;

La raison pour laquelle le contrôle ne fonctionne pas lorsque vous avez changé votre code pour simplement être un double était parce que vous aviez:

double trans = trackbar1.Value / 5000;

qui a interprété le 5000 comme un nombre entier, de sorte que votre trans la valeur était toujours zéro. En définissant explicitement une valeur numérique à virgule flottante en ajoutant .0 le compilateur peut maintenant l'interpréter comme un double et effectuer le bon calcul.


42
2018-03-06 08:07



La meilleure solution est:

this.Opacity = decimal.ToDouble(trackBar1.Value/5000);

38
2018-05-13 02:10