Ondalık Sayı'yı Çifte Dönüştür


673

Track-BarBir Formopaklığı değiştirmek için bir kullanmak istiyorum .

Bu benim kodum:

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

Uygulamayı oluşturduğumda, şu hatayı veriyor:

Dolaylı türünü dönüştürülemez decimaliçindouble

Kullanmayı denedim transve doublesonra Controlçalışmıyor. Bu kod, geçmiş bir VB.NET projesinde iyi çalıştı.


11
Ayrıca, Ondalık, Double değeri kadar geniş bir değeri temsil edemez. Ondalık yalnızca +/- 7.9228162514264337593543950335E + 28'e kadar çıkabilir; bir çift +/- 1.79769313486232E + 308 kadar gidebilir
TraumaPony


8
Birisi bunu bir kopya olarak işaretlemelidir.
Ivan

8
@Ivan: Bu hiç SO sorulan 4. soru ...
Nikolas

1
@Nikolas: Gerçekten. Bugün burada izlendi.
Haziran

Yanıtlar:


447

Bunun doublegibi açık bir oyuncu seçimi gerekli değildir:

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

Sabitin 5000.0(veya 5000d) olarak tanımlanması yeterlidir:

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

123

"Decimal vs Double?" Genel sorusu için daha genel bir yanıt: Hassasiyeti korumak için parasal hesaplamalar için ondalık , Küçük farklılıklardan etkilenmeyen bilimsel hesaplamalar için Double . Double, CPU'ya özgü bir tür olduğundan (dahili gösterim taban 2'de depolanır ), Double ile yapılan hesaplamalar Ondalıktan daha iyi performans gösterir ( dahili olarak taban 10'da temsil edilir ).


83

Kodunuz VB.NET'te düzgün çalıştı, çünkü dolaylı olarak herhangi bir yayın yapıyor, C # hem örtük hem de açık olanlara sahip.

C # 'da, doğruluğu kaybettiğinizde ondalıktan ikiye dönüşüm açıktır. Örneğin, 1.1 çift olarak doğru bir şekilde ifade edilemez, ancak ondalık sayı olarak ifade edilebilir ( bunun nedeni için " Kayan nokta sayıları - düşündüğünüzden daha yanlış " konusuna bakın ).

VB'de dönüşüm sizin için derleyici tarafından eklendi:

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

Bu (double)açıkça C # 'da belirtilmelidir, ancak VB'nin daha' affedici 'derleyicisi tarafından ima edilebilir .


80

Neden 5000'e bölüyorsun? TrackBar'ın Minimum ve Maksimum değerlerini 0 ile 100 arasında ayarlayın ve Opaklık yüzdesi için Değeri 100'e bölün. Aşağıdaki minimum 20 örnek, formun tamamen görünmez olmasını önler:

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
Bu sorunu çözmüyor mu? 5000OP ile ilgili bir sorun yerine, bir sorun olurdu 100?
JWW

62

İki sorunun var. İlk olarak, Opacityondalık bir değer değil, bir çift gerektirir. Derleyici, ondalık ve çift arasında bir dönüşüm olsa da, bunun çalışması için belirtmeniz gereken açık bir dönüşüm olduğunu söylüyor. İkincisi, TrackBar.Valuebir tamsayı değeridir ve bir int değerini int ile bölmek, ne tür bir değişkene atadığınıza bakılmaksızın int ile sonuçlanır. Bu durumda int'den ondalık veya ikiye kadar örtük bir döküm vardır - çünkü döküm yaparken hassasiyet kaybı olmaz - bu nedenle derleyici şikayet etmez, ancak aldığınız değer her zaman 0'dır, çünkütrackBar.ValueÇözüm, kodunuzu double (Opaklık için yerel tür) kullanacak şekilde değiştirmektir ve sabiti açıkça bir çift yaparak - aritmetiği artırma etkisi ya da trackBar.Valueikiye döküm yapacaktır aynı şeyi yapacaktır - ya da her ikisini birden. Oh, ve başka bir yerde kullanılmadıkça ara değişkene ihtiyacınız yok. Sanırım derleyici onu optimize edecek.

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

58

Benim düşünceme göre, olabildiğince açık olması arzu edilir. Bu koda netlik katar ve sonunda okuyabilen programcı arkadaşlarınıza yardımcı olur.

.0Numaraya a eklemenin yanı sıra (veya yerine) kullanabilirsiniz decimal.ToDouble().

İşte bazı örnekler:

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

this.OpacityBir çift değer gibi görünüyor ve derleyici ondalık bir değeri tıklatmaya çalışmanızı sevmiyor.


50

Opaklık özelliği çift tiptedir:

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

ya da sadece:

this.Opacity = trackBar1.Value / 5000.0;

veya:

this.Opacity = trackBar1.Value / 5000d;

Bir tamsayı olduğu ve bir tamsayı bölümü gerçekleştireceği ve sonuç bir tamsayı olacağı için bir çift ​​bölümü zorlamak için 5000.0(veya 5000d) kullandığım dikkat edin trackBar1.Value.


49

Bunun 5000.0yerine kullanmalısınız 5000.


47

WinForms kullandığınızı varsayarsak Form.Opacity, bir türdür double, bu nedenle şunları kullanmalısınız:

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

Başka bir yerde değere ihtiyacınız yoksa, yazmak daha kolaydır:

this.Opacity = trackBar1.Value / 5000.0;

Kodunuzu sadece bir çift olarak değiştirdiğinizde kontrolün çalışmamasının nedeni şuydu:

double trans = trackbar1.Value / 5000;

ki bu 5000bir tamsayı olarak yorumlanır ve aynı trackbar1.Valuezamanda bir tamsayı olduğu için transdeğeriniz her zaman sıfırdır. .0Derleyiciyi ekleyerek sayısal sayıyı açıkça bir kayar nokta değeri haline getirerek, şimdi bunu bir ikili olarak yorumlayabilir ve uygun hesaplamayı yapabilir.


41

En iyi çözüm:

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

41

Yana Opacitybir çift değerdir, sadece baştan bir çift kullanmak ve hiç dökme değil, ancak herhangi bir hassas gevşek kalmamak bölünürken, çift kullandığınızdan emin olacaktır

Opacity = trackBar1.Value / 5000.0;


0

Bunu dene:

Opacity = decimal.ToDouble(trackBar1.Value / 5000.0);```
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.