Convertir décimal en double


672

Je veux utiliser a Track-Barpour changer Forml'opacité de a.

Voici mon code:

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

Lorsque je crée l'application, cela donne l'erreur suivante:

Impossible de convertir implicitement le type decimalendouble

J'ai essayé d'utiliser transet doublepuis Controlça ne marche pas. Ce code a bien fonctionné dans un ancien projet VB.NET.


11
En outre, Decimal ne peut pas représenter une valeur aussi large qu'un Double. La décimale ne peut aller que jusqu'à +/- 7,9228162514264337593543950335E + 28; alors qu'un Double peut aller jusqu'à +/- 1.79769313486232E + 308
TraumaPony


8
Quelqu'un devrait marquer celui-ci comme doublon.
Ivan

8
@Ivan: C'est la 4ème question posée sur SO ever ...
Nikolas

1
@Nikolas: En effet. Tracé ici aujourd'hui.
juin

Réponses:


447

Un cast explicite pour doubleaimer cela n'est pas nécessaire:

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

Identifier la constante comme 5000.0(ou comme 5000d) suffit:

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

123

Une réponse plus générique à la question générique "Décimal vs Double?": Décimal pour les calculs monétaires afin de préserver la précision, Double pour les calculs scientifiques qui ne sont pas affectés par de petites différences. Étant donné que Double est un type natif du CPU (la représentation interne est stockée dans la base 2 ), les calculs effectués avec Double fonctionnent mieux que Decimal (qui est représenté en base 10 en interne).


83

Votre code a bien fonctionné dans VB.NET car il effectue implicitement toutes les conversions, tandis que C # en a à la fois implicites et explicites.

En C #, la conversion de décimal en double est explicite car vous perdez en précision. Par exemple, 1.1 ne peut pas être exprimé avec précision sous la forme d'un double, mais peut être décimal (voir « Numéros à virgule flottante - plus imprécis que vous ne le pensez » pour la raison).

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

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

Cela (double)doit être explicitement indiqué en C #, mais peut être implicite par le compilateur plus «indulgent» de VB.


80

Pourquoi divisez-vous par 5000? Définissez simplement les valeurs minimum et maximum du TrackBar entre 0 et 100, puis divisez la valeur par 100 pour le pourcentage d'opacité. L'exemple minimum 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;
}

5
Cela ne déplacerait-il pas simplement le problème? Plutôt qu'un problème avec 5000, OP aurait un problème avec 100?
JWW

62

Vous avez deux problèmes. Tout d'abord, Opacitynécessite une valeur double et non décimale. Le compilateur vous dit que bien qu'il y ait une conversion entre décimal et double, c'est une conversion explicite que vous devez spécifier pour que cela fonctionne. La seconde est qu'il TrackBar.Values'agit d'une valeur entière et la division d'un int par un int entraîne un int quel que soit le type de variable auquel vous l'assignez. Dans ce cas, il y a une conversion implicite de int en décimal ou double - car il n'y a aucune perte de précision lorsque vous effectuez la conversion - donc le compilateur ne se plaint pas, mais la valeur que vous obtenez est toujours 0, probablement, cartrackBar.Valueest toujours inférieur à 5000. La solution est de changer votre code pour utiliser le double (le type natif pour l'opacité) et faire de 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 transtyper trackBar.Valueen double , qui fera la même chose - ou les deux. Oh, et vous n'avez pas besoin de la variable intermédiaire à moins qu'elle ne soit utilisée ailleurs. Je suppose que le compilateur l'optimiserait de toute façon.

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

58

À 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 (ou au lieu de) d'ajouter un .0au 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);

57

Cela ressemble à this.Opacityune double valeur, et le compilateur n'aime pas que vous essayiez d'y insérer une valeur décimale.


50

La propriété Opacity 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) pour forcer une double division car trackBar1.Valueest un entier et il effectuerait une division entière et le résultat serait un entier.


49

Vous devez utiliser à la 5000.0place de 5000.


47

En supposant que vous utilisez WinForms, Form.Opacityest de type double, vous devez 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 modifié votre code pour qu'il soit simplement un double est dû au fait que vous aviez:

double trans = trackbar1.Value / 5000;

qui a interprété le 5000comme un entier, et parce que trackbar1.Valuec'est aussi un entier, votre transvaleur était toujours nulle. En faisant explicitement du numérique une valeur à virgule flottante en ajoutant le .0compilateur, il peut désormais l'interpréter comme un double et effectuer le calcul approprié.


41

La meilleure solution est:

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

41

Puisqu'il Opacitys'agit d'une valeur double, j'utiliserais simplement un double dès le départ et pas du tout, mais assurez-vous d'utiliser un double lors de la division afin de ne perdre aucune précision

Opacity = trackBar1.Value / 5000.0;


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.