将小数转换为双精度?
我想使用跟踪栏来更改表单的不透明度。
这是我的代码:
decimal trans = trackBar1.Value / 5000; this.Opacity = trans;
当我构建应用程序时,它给出以下错误:
Cannot implicitly convert type 'decimal' to 'double'.
我尝试使用trans
和double
,但是控件不起作用。这段代码在过去的VB.NET项目中运行良好。
解决方案:
不需要像这样的显式强制转换为两倍:
double trans = (double) trackBar1.Value / 5000.0;
将常量标识为" 5000.0"(或者" 5000d")就足够了:
double trans = trackBar1.Value / 5000.0; double trans = trackBar1.Value / 5000d;
听起来" this.Opacity"是一个双精度值,并且编译器不喜欢我们尝试将十进制值填充到其中。
通用问题"十进制与双精度?"的一个更通用的答案:十进制用于货币计算以保持精度,而双精度用于科学计算不受小差异的影响。由于Double是CPU固有的类型(内部表示形式存储在基数2中),因此使用Double进行的计算要好于十进制(内部表示在基数10中)。
我认为,希望尽可能明确。这增加了代码的清晰度,并帮助可能最终阅读该代码的其他程序员。
除了(或者代替)在数字后添加" .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);
代码在VB.NET中运行良好,因为它隐式地执行任何强制转换,而Chas隐式和显式强制转换。
在C中,从十进制到双精度的转换很明显,因为我们会失去精度。例如,1.1不能准确地表示为双精度数,而可以精确地表示为十进制数(有关原因,请参见"浮点数比我们想象的更不准确")。
在VB中,编译器为我们添加了转换:
decimal trans = trackBar1.Value / 5000m; this.Opacity = (double) trans;
必须在C#中明确声明(double)
,但是可以由VB的"更宽容"的编译器来隐含。
你为什么要除以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; }
我们应该使用" 5000.0"而不是" 5000"。
你有两个问题。首先,"不透明度"要求为双精度值,而不是十进制值。编译器告诉我们,虽然在十进制和双精度之间存在转换,但是我们需要指定它是一个显式转换,以使其起作用。第二个是TrackBar.Value
是一个整数值,将int除以int会得到一个int,无论我们将变量分配给哪种类型。在这种情况下,存在从int到十进制或者double的隐式转换,因为执行转换时不会损失精度,因此编译器不会抱怨,但是我们获得的值始终为0,大概是因为trackBar.Value
始终小于5000。解决方案是将代码更改为使用double(不透明度的本机类型),并通过将常量显式设置为double来进行浮点算术,这将促进算术或者强制转换trackBar
。将值增加一倍,这将执行相同的操作或者同时执行这两项操作。哦,我们不需要中间变量,除非在其他地方使用了中间变量。我的猜测是,无论如何编译器都会对其进行优化。
trackBar.Opacity = (double)trackBar.Value / 5000.0;