将小数转换为双精度?

时间:2020-03-05 15:55:43  来源:igfitidea点击:

我想使用跟踪栏来更改表单的不透明度。

这是我的代码:

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

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

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

我尝试使用transdouble,但是控件不起作用。这段代码在过去的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;