Tout en appliquant l'opacité à un formulaire, devrions-nous utiliser une valeur décimale ou 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 implicitement le type 'decimal' en 'double' .

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

0
ajouté édité
Vues: 74
En outre, Decimal ne peut pas représenter une valeur aussi large qu'un double. La valeur décimale peut seulement aller jusqu'à +/- 7,9228162514264337593543950335E + 28; alors qu'un double peut aller jusqu'à +/- 1.79769313486232E + 308
ajouté l'auteur TraumaPony, source

13 Réponses

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

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

L'identification de la constante 5000.0 (ou 5000d ) est suffisante:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
1
ajouté

Une réponse plus générique pour la question générique "Décimal vs Double?": Décimal </ strong> pour les calculs monétaires afin de préserver la précision, Double </ strong> 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 </ em>), les calculs effectués avec Double sont meilleurs que les décimaux (représentés dans base 10 </ em> intérieurement).

0
ajouté

Il semble que this.Opacity soit une valeur double, et le compilateur n'aime pas que vous essayiez d'entasser une valeur décimale dedans.

0
ajouté

À 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 d ') 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);
0
ajouté

Vous avez deux problèmes. Premièrement, 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. La seconde est que TrackBar.Value est une valeur entière et diviser un int par un int conduit à 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 lorsque vous faites le cast - donc le compilateur ne se plaint pas, mais la valeur que vous obtenez est toujours 0, probablement 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 en virgule flottante en faisant explicitement de la constante un double - ce qui aura l'effet de la promotion de l'arithmétique - ou la conversion de trackBar.Value en double, 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;
0
ajouté

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 en tant que décimal (voir " nombres à virgule flottante - plus inexactes que vous 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;

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

0
ajouté

La meilleure solution est:

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

Vous devriez utiliser 5000.0 au lieu de 5000 .

0
ajouté

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;
}
0
ajouté

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 parce que trackBar1.Value est un entier et il effectuerait une division entière et le résultat serait un entier .

0
ajouté

En supposant que vous utilisez WinForms, Form.Opacity est 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 changé votre code pour simplement être un double était parce que vous aviez:

double trans = trackbar1.Value / 5000;

qui interprétait le 5000 comme un entier, donc votre valeur trans était toujours nulle. En faisant explicitement une valeur numérique à virgule flottante en ajoutant le .0 , le compilateur peut maintenant l'interpréter comme un double et effectuer le calcul correct.

0
ajouté

Puisque Opacity est une valeur double, je voudrais juste utiliser un double dès le départ et ne pas lancer 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;
0
ajouté
this.Opacity = trackBar1.Value / 5000d;
0
ajouté