在对表单应用不透明度的同时,我们应该使用小数还是双精度值?

est_ut 发布于 2018-02-02 c# 最后更新 2018-02-02 11:24 642 浏览

我想使用一个轨道栏来改变窗体的不透明度。 这是我的代码:

decimal trans = trackBar1.Value/5000;
this.Opacity = trans;
当我构建应用程序时,会出现以下错误:
Cannot implicitly convert type 'decimal' to 'double'.
我尝试使用transdouble但是然后控制不起作用。这个代码在过去的VB.NET项目中工作得很好。
已邀请:

jneque

赞同来自:

显式转换为double是没有必要的。

double trans = (double)trackBar1.Value/5000.0;
将常量标识为5000.0(或5000d)就足够了:
double trans = trackBar1.Value/5000.0;
double trans = trackBar1.Value/5000d;

jquia

赞同来自:

这听起来像this.Opacity是一个双精度值,编译器不喜欢你试图塞入一个十进制值。

malias

赞同来自:

对于一般问题“十进制与双精度?”:Decimal用于货币计算以更好地保留精度Double用于不受小差异影响的科学计算。由于Double是CPU本地类型(内部表示存储在base 2中),因此使用Double进行的计算执行得更好,然后执行Decimal(在base 10内部表示)。

sit_in

赞同来自:

我认为,尽可能明确是可取的。这增加了代码的清晰度,并帮助可能最终读取它的程序员。 除了(或代替)将.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);

punde

赞同来自:

你的代码在VB.NET中工作正常,因为它隐式地执行任何强制转换,而C#既有隐式的,也有明确的。 在C#中,从十进制到双精度的转换是明确的,因为您失去了精度。例如1.1不能准确地表示为double,但可以用十进制表示(请参阅“Floating point numbers - more inaccurate than you think”,原因为何)。 在VB中,编译器为你添加了转换:

decimal trans = trackBar1.Value/5000m;
this.Opacity = (double) trans;
(double)必须在C#中明确声明,但可以通过VB更“宽容”的编译器来implied

phic

赞同来自:

你为什么除以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;
}

asaepe

赞同来自:

您应该使用5000.0而不是5000

quia_a

赞同来自:

你有两个问题。首先,Opacity需要双精度值,而不是十进制值。编译器告诉你,虽然在十进制和双精度之间有一个转换,但它是一个显式的转换,你需要指定它才能工作。第二个是TrackBar.Value是一个整数值,并且将一个int除以int得到的结果是一个int,而不管你分配给哪个类型的变量。在这种情况下,存在从int到decimal或double的隐式转换 - 因为在执行转换时没有精度损失 - 所以编译器不会抱怨,但是您得到的值始终为0,因为trackBar.Value是总是小于5000.解决方法是将代码更改为使用double(Opacity的本机类型),并通过显式将常量设置为double来执行浮点运算 - 这将具有促进算术运算的效果 - 或者将trackBar.Value转换为double ,这将做同样的事情,或两者兼而有之。哦,你不需要中间变量,除非在其他地方使用。我的猜测是编译器会优化它,反正。

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

gvel

赞同来自:

Opacity属性是双重类型:

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是一个整数,它将执行整数除法,结果将是一个整数。

wearum

赞同来自:

假设你正在使用WinForms,Form.Opacity的类型是double,所以你应该使用:

double trans = trackBar1.Value/5000.0;
this.Opacity = trans;
除非你需要别处的价值,否则写起来会更简单:
this.Opacity = trackBar1.Value/5000.0;
当您将代码更改为简单双精度时,控件不起作用的原因是因为您有:
double trans = trackbar1.Value/5000;
5000解释为整数,所以您的trans值始终为零。通过添加.0明确地将数字设置为浮点值,编译器现在可以将其解释为double并执行正确的计算。

zomnis

赞同来自:

最好的解决方案是:

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

aet

赞同来自:

由于Opacity是一个双精度值,所以我只是从一开始就用一个double而不是强制转换,但是在分割的时候一定要使用double,所以你不会失去精度

Opacity = trackBar1.Value/5000.0;

punde

赞同来自:

this.Opacity = trackBar1.Value/5000d;