Converti decimale in doppio


672

Voglio usare a Track-Barper cambiare Forml'opacità di a.

Questo è il mio codice:

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

Quando compilo l'applicazione, viene visualizzato il seguente errore:

Impossibile convertire in modo implicito il tipo decimalindouble

Ho provato a usare transe doublema poi Controlnon funziona. Questo codice ha funzionato bene in un precedente progetto VB.NET.


11
Inoltre, il decimale non può rappresentare un valore così ampio come un doppio. Il decimale può salire fino a +/- 7.9228162514264337593543950335E + 28; mentre un Double può salire a +/- 1.79769313486232E + 308
TraumaPony,


8
Qualcuno dovrebbe contrassegnarlo come duplicato.
Ivan,

8
@Ivan: Questa è la quarta domanda posta su SO mai ...
Nikolas

1
@Nikolas: Anzi. Rintracciato qui oggi.
Giugno

Risposte:


447

doubleNon è necessario un cast esplicito per amare questo:

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

Identificare la costante come 5000.0(o come 5000d) è sufficiente:

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

123

Una risposta più generica alla domanda generica "Decimale vs Doppio?": Decimale per i calcoli monetari per preservare la precisione, Doppio per i calcoli scientifici che non sono interessati da piccole differenze. Poiché Double è un tipo nativo della CPU (la rappresentazione interna è memorizzata nella base 2 ), i calcoli eseguiti con Double hanno prestazioni migliori di Decimal (che è rappresentato nella base 10 internamente).


83

Il tuo codice ha funzionato bene in VB.NET perché implica implicitamente qualsiasi cast, mentre C # ha sia impliciti che espliciti.

In C # la conversione da decimale a doppio è esplicita man mano che si perde precisione. Ad esempio 1.1 non può essere espresso con precisione come doppio, ma come decimale (vedere " Numeri in virgola mobile - più imprecisi di quanto si pensi " per il motivo).

In VB la conversione è stata aggiunta per te dal compilatore:

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

Ciò (double)deve essere esplicitamente dichiarato in C #, ma può essere implicito dal compilatore più "tollerante" di VB.


80

Perché stai dividendo per 5000? Basta impostare i valori minimo e massimo della TrackBar tra 0 e 100, quindi dividere il valore per 100 per la percentuale di opacità. L'esempio di seguito minimo 20 impedisce al modulo di diventare completamente invisibile:

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
Questo non sposta semplicemente il problema? Piuttosto che un problema con 5000, OP avrebbe un problema con 100?
JWW

62

Hai due problemi. Innanzitutto, Opacityrichiede un valore doppio, non decimale. Il compilatore ti sta dicendo che mentre c'è una conversione tra decimale e doppio, è una conversione esplicita che devi specificare affinché funzioni. Il secondo è che TrackBar.Valueè un valore intero e la divisione di un int per un int determina un int, indipendentemente dal tipo di variabile a cui lo si assegna. In questo caso c'è un cast implicito da int a decimale o doppio - perché non c'è perdita di precisione quando esegui il cast - quindi il compilatore non si lamenta, ma il valore che ottieni è sempre 0, presumibilmente, poichétrackBar.Valueè sempre inferiore a 5000. La soluzione è cambiare il codice per usare il doppio (il tipo nativo per l'opacità) e fare l'aritmetica in virgola mobile rendendo esplicitamente la doppia un doppio - che avrà l'effetto di promuovere l'aritmetica - o lanciare il trackBar.Valuedoppio , che farà la stessa cosa - o entrambi. Oh, e non hai bisogno della variabile intermedia a meno che non sia usata altrove. La mia ipotesi è che il compilatore lo ottimizzerebbe comunque, comunque.

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

58

A mio avviso, è auspicabile essere il più esplicito possibile. Questo aggiunge chiarezza al codice e aiuta i tuoi colleghi programmatori che potrebbero eventualmente leggerlo.

Oltre a (o anziché) aggiungere .0a al numero, è possibile utilizzare decimal.ToDouble().

Ecco alcuni esempi:

// 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

Sembra this.Opacityun doppio valore e al compilatore non piace che tu provi a inserire un valore decimale in esso.


50

La proprietà Opacity è di doppio tipo:

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

o semplicemente:

this.Opacity = trackBar1.Value / 5000.0;

o:

this.Opacity = trackBar1.Value / 5000d;

Si noti che sto usando 5000.0(o 5000d) per forzare una doppia divisione perché trackBar1.Valueè un numero intero e si comporterebbe una divisione intera e il risultato sarebbe un numero intero.



47

Supponendo che tu stia usando WinForms, Form.Opacityè di tipo double, quindi dovresti usare:

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

A meno che non sia necessario il valore altrove, è più semplice scrivere:

this.Opacity = trackBar1.Value / 5000.0;

Il motivo per cui il controllo non funziona quando hai cambiato il tuo codice per essere semplicemente un doppio era perché avevi:

double trans = trackbar1.Value / 5000;

che interpretava 5000come un numero intero e, poiché trackbar1.Valueè anche un numero intero, il transvalore era sempre zero. Rendendo esplicitamente il valore numerico in virgola mobile aggiungendo .0il compilatore, ora è possibile interpretarlo come doppio ed eseguire il calcolo corretto.


41

La migliore soluzione è:

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

41

Dato che Opacityè un doppio valore, userò solo un doppio fin dall'inizio e non lo lancerei affatto, ma assicurati di usare un doppio quando dividi in modo da non perdere alcuna precisione

Opacity = trackBar1.Value / 5000.0;


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.