在对表单应用不透明度的同时,我们应该使用小数还是双精度值?
我想使用一个轨道栏来改变窗体的不透明度。
这是我的代码:
decimal trans = trackBar1.Value / 5000; this.Opacity = trans;
当我构build应用程序时,会出现以下错误:
不能隐式地将types
'decimal'
转换为'double'
。
我尝试使用trans
和double
但然后控制不起作用。 这个代码在过去的VB.NET项目中工作得很好。
显式转换为double是没有必要的。
double trans = (double)trackBar1.Value / 5000.0;
识别常量为5000.0
(或5000d
)就足够了:
double trans = trackBar1.Value / 5000.0; double trans = trackBar1.Value / 5000d;
一般问题“十进制与双精度?”的更一般的答案:货币计算用十进制来保持精度, 双倍用于不受小差异影响的科学计算。 由于Double是CPU原生types(内部表示存储在基址2中 ),所以使用Double执行的计算performance更好,然后执行Decimal(在内部以10为底数表示)。
你的代码在VB.NET中工作正常,因为它隐式地执行任何强制转换,而C#同时具有隐式和显式。
在C#中,从十进制到双精度的转换是明确的,因为您失去了精度。 例如1.1不能精确地表示为double,但可以作为小数(请参阅“ 浮点数 – 比您想象的更不精确 ”)。
在VB中,编译器为你添加了转换:
decimal trans = trackBar1.Value / 5000m; this.Opacity = (double) trans;
这(double)
必须在C#中明确表示,但可以由VB的更宽容的编译器隐含 。
你为什么除以5000? 只需将TrackBar的“最小值”和“最大值”设置为0到100之间,然后将“不透明度”百分比值除以100即可。 下面的最less20个例子可以防止表单完全隐藏:
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; }
你有两个问题。 首先, Opacity
需要双倍,而不是十进制值。 编译器告诉你,虽然在十进制和双精度之间有一个转换,但它是一个显式的转换,你需要指定它来工作。 第二个是TrackBar.Value
是一个整数值,并且将一个int除以int得到的结果是一个int,不pipe你分配给哪个types的variables。 在这种情况下,存在从int到decimal或double的隐式转换 – 因为在执行转换时没有精度损失 – 所以编译器不会抱怨,但是您得到的值始终为0,大概是因为trackBar.Value
总是小于5000.解决方法是更改您的代码使用双(不透明度的本机types),并通过显式使常量为双 – 这将具有促进算术效果或投射trackBar.Value
做浮点运算trackBar.Value
翻倍,这将做同样的事情,或两者兼而有之。 哦,你不需要中间variables,除非在其他地方使用。 我的猜测是编译器会优化它,反正。
trackBar.Opacity = (double)trackBar.Value / 5000.0;
我认为,尽可能明确是可取的。 这增加了代码的清晰度,并帮助可能最终读取它的程序员。
除了(或者不是)将.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);
这听起来是这样的。不this.Opacity
是一个双重值,编译器不喜欢你试图将十进制值塞入它。
您应该使用5000.0
而不是5000
。
不透明度属性是双重types:
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
是一个整数,它将执行整数除法,结果将是一个整数。
假设你正在使用WinForms, Form.Opacity
是double
types,所以你应该使用:
double trans = trackBar1.Value / 5000.0; this.Opacity = trans;
除非你需要别处的价值,否则写起来会更简单:
this.Opacity = trackBar1.Value / 5000.0;
当您将代码更改为简单双精度时,控件不起作用的原因是因为您有:
double trans = trackbar1.Value / 5000;
将5000
解释为一个整数,所以你的trans
值总是为零。 通过添加.0
明确地将数字设置为浮点值,编译器现在可以将其解释为double并执行正确的计算。
最好的解决scheme是:
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
由于Opacity
是一个双重价值,我只是从一开始就使用一个双,而不是所有,但一定要使用一个双倍的时候分开,所以你不要失去任何精度
Opacity = trackBar1.Value / 5000.0;
this.Opacity = trackBar1.Value / 5000d;