2008-07-31 38 views
543

我想使用軌跡欄來更改窗體的不透明度。將不透明度應用於表單時,我們應該使用小數還是雙精度值?

這是我的代碼:

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

當我構建應用程序,它提供了以下錯誤:

Cannot implicitly convert type 'decimal' to 'double' .

我嘗試使用transdouble但隨後的控制不起作用。此代碼在過去的VB.NET項目中運行良好。

+8

此外,十進制不能代表同樣寬的值作爲雙人。十進制只能達到+/- 7.9228162514264337593543950335E + 28;而一個Double可以達到+/- 1.79769313486232E + 308 – TraumaPony 2008-09-21 04:09:42

回答

391

顯式轉換到加倍像這不是必需的:

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

識別常數5000.0(或作爲5000d)足以:

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

這聽起來像this.Opacity是雙值,並且編譯器不喜歡你嘗試將十進制值塞進它中。

112

一個更通用的答案一般問題「十進制VS雙?」:十進制貨幣計算,以保持精度,對於沒有得到受微小差異的科學計算。由於Double是CPU原生類型(內部表示存儲在的基數2中),因此使用Double執行的計算性能會更好,然後執行Decimal(內部表示爲基數10)。

55

在我看來,最好儘可能明確。這增加了代碼的清晰度,並幫助可能最終讀取它的程序員。

除了(或代替)將.0附加到數字之外,您可以使用decimal.ToDouble()

下面是一些例子:

// Example 1 
double transperancy = trackBar1.Value/5000; 
this.Opacity = decimal.ToDouble(transperancy); 

// Example 2 - with inline temp 
this.Opacity = decimal.ToDouble(trackBar1.Value/5000); 
74

您的代碼在VB.NET工作得很好,因爲它確實隱含任何類型轉換,而C#既有隱和外顯的。

在C#中,從十進制到雙精度的轉換是明確的,因爲您失去了準確性。例如1.1不能準確地表示爲雙精度,但可以作爲小數(因爲原因,請參閱「Floating point numbers - more inaccurate than you think」)。

在VB是由編譯器爲你添加的轉換:

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

(double)必須在C#中明確闡述,但可以通過VB的更多的「寬容」編譯器暗示

73

你爲什麼除以5000?只需將TrackBar的「最小值」和「最大值」設置爲0到100之間,然後將「不透明度」百分比值除以100即可。低於最低20示例阻止形式變得完全看不見:

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; 
} 
+3

這難道不會只是解決問題嗎?與`5000`不一樣的問題,OP會對`100`有問題? – jww 2014-09-22 21:17:56

45

您應該使用5000.0而不是5000

56

你有兩個問題。首先,Opacity需要雙精度值,而不是十進制值。編譯器告訴你,雖然在十進制和雙精度之間有一個轉換,但它是一個顯式轉換,你需要指定它以使其工作。第二個是TrackBar.Value是一個整數值,並且將一個int除以int得到的結果是一個int,而不管分配給它的是哪種類型的變量。在這種情況下,存在從int到decimal或double的隱式轉換 - 因爲在執行轉換時沒有精度損失 - 所以編譯器不會發出抱怨,但是您得到的值始終爲0,可能是因爲trackBar.Value是總是小於5000.解決方案是將您的代碼更改爲使用double(Opacity的本機類型),並通過明確地將該常量設置爲double來執行浮點運算 - 這將具有促進算術運算的效果 - 或者將trackBar.Value的值加倍,這將做同樣的事情 - 或兩者兼而有之。哦,你不需要中間變量,除非在其他地方使用。無論如何,我的猜測是編譯器會優化它。

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

Opacity屬性是double類型:

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

或者乾脆:

this.Opacity = trackBar1.Value/5000.0; 

或:

this.Opacity = trackBar1.Value/5000d; 

請注意,我用的5000.0(或5000d)強制執行雙除法,因爲trackBar1.Value是一個整數,它將執行整數除法並且結果將是整數。

42

假設你正在使用的WinForms,Form.Opacitydouble類型的,所以你應該使用:

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

除非你需要在其他地方的價值,這是簡單的寫:

this.Opacity = trackBar1.Value/5000.0; 

的原因當您將您的代碼更改爲簡單雙倍時,控件不起作用,因爲您有:

double trans = trackbar1.Value/5000; 

5000解釋爲整數,因此您的trans值始終爲零。通過添加.0明確地將數字設置爲浮點值,編譯器現在可以將其解釋爲double並執行正確的計算。

38

最好的解決辦法是:

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

由於Opacity是一個雙重價值,我只想用一個雙從一開始就與不投所有,但可以肯定的劃分,所以你不要當使用雙「T丟失任何精度

Opacity = trackBar1.Value/5000.0; 
31
this.Opacity = trackBar1.Value/5000d; 
相關問題