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

我想使用轨迹栏来更改窗体的不透明度。

这是我的代码:

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

当我构建应用程序时,会出现以下错误:

无法将类型'decimal'隐式转换为'double'

我试过使用 transdouble ,但是这个控件不起作用。此代码在过去的VB.NET项目中运行良好。

0
额外 编辑
意见: 70
此外,Decimal不能表示与Double相同的宽度值。十进制只能达到+/- 7.9228162514264337593543950335E + 28;而Double可以达到+/- 1.79769313486232E + 308
额外 作者 TraumaPony,

13 答案

没有必要明确地强制转换成这样的形式:

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

将常量标识为 5000.0 (或 5000d )就足够了:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
1
额外

通用问题“小数还是双精度?”的更一般答案:用于货币计算以保留精度的小数</ strong>,用于不受小差异影响的科学计算的 Double </ strong> 。由于Double是CPU原生类型(内部表示存储在 base 2 </ em>中),因此使用Double执行的计算执行得更好,然后Decimal(以 base 10 </ em>内部)。

0
额外

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

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);
0
额外

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

trackBar.Opacity = (double)trackBar.Value / 5000.0;
0
额外

你的代码在VB.NET中运行良好,因为它隐含地执行了任何强制转换,而C#同时具有隐式和显式两种转换。

在C#中,从小数到双精度的转换是明确的,因为您失去了准确性。例如1.1不能精确地表示为double,但可以用十进制表示(请参阅“浮点数 - 比你想象的更不准确)。

在VB中,编译器为您添加了转换:

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

这个(double)必须在C#中明确声明,但可以通过VB的更多'forgiving'编译器来暗示</ em>。

0
额外

最好的解决方案是:

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

您应该使用 5000.0 而不是 5000

0
额外

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

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

0
额外

假设您使用的是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并执行正确的计算。

0
额外

由于 Opacity 是一个双精度值,因此我只会从一开始就使用double而不是完全投射,但在分割时一定要使用double,所以您不会失去任何精度

Opacity = trackBar1.Value / 5000.0;
0
额外
this.Opacity = trackBar1.Value / 5000d;
0
额外