将十进制转换为双倍?

时间:2008-07-31 21:42:53

标签: c# floating-point type-conversion double decimal

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

这是我的代码:

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

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

  

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

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

15 个答案:

答案 0 :(得分:420)

没有必要像这样加倍显式演员:

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

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

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;

答案 1 :(得分:120)

通用问题“Decimal vs Double?”的更通用的答案: Decimal 用于货币计算以保持精度, Double 用于不受影响的科学计算差异很小。由于Double是CPU的原生类型(内部表示存储在 base 2 中),因此使用Double执行的计算优于Decimal(在 base 10 中表示)内部)。

答案 2 :(得分:80)

您的代码在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;

必须在C#中明确声明(double),但VB的“宽容”编译器可以暗示

答案 3 :(得分:77)

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

答案 4 :(得分:60)

你有两个问题。首先,Opacity需要一个double,而不是十进制值。编译器告诉您,虽然十进制和双精度之间存在转换,但它是一个显式转换,您需要指定它才能使其工作。第二个是TrackBar.Value是一个整数值,将int除以int会产生一个int,无论你指定什么类型的变量。在这种情况下,存在从int到decimal或double的隐式转换 - 因为在执行转换时没有精度损失 - 所以编译器不会抱怨,但是你得到的值总是0,大概是因为{{ 1}}总是小于5000.解决方案是将代码更改为使用double(Opacity的本机类型)并通过显式使常量变为double来执行浮点运算 - 这将具有促进算术的效果 - 或者将trackBar.Value转换为double,这将执行相同的操作 - 或两者兼而有之。哦,除非在别处使用,否则你不需要中间变量。无论如何,我的猜测是编译器会优化它。

trackBar.Value

答案 5 :(得分:57)

在我看来,希望尽可能明确。这增加了代码的清晰度,并帮助最终可能阅读它的程序员。

除了(或代替)在号码上附加.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);

答案 6 :(得分:55)

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

答案 7 :(得分:47)

您应该使用5000.0代替5000

答案 8 :(得分:45)

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

答案 9 :(得分:45)

假设您使用的是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解释为整数,并且因为trackbar1.Value也是一个整数,所以trans值始终为零。通过添加.0显式地使数字成为浮点值,编译器现在可以将其解释为double并执行正确的计算。

答案 10 :(得分:39)

由于Opacity是一个双精度值,我只是从一开始就使用双精度而根本不使用双精度值,但一定要在分割时使用双精度,这样你就不会失去任何精度

Opacity = trackBar1.Value / 5000.0;

答案 11 :(得分:39)

最佳解决方案是:

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

答案 12 :(得分:33)

this.Opacity = trackBar1.Value / 5000d;

答案 13 :(得分:3)

尝试一下:

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

答案 14 :(得分:-1)

我们可以做这样的事情:

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

或简化为:

this.Opacity = trackBar1.Value / 5000.0;

您还可以使用内置的转换功能,例如Decimal.ToDouble()

double trans = trackBar1.Value / 5000.0;
this.Opacity = Decimal.ToDouble(trans);

您也可以使用简化形式,但是我不建议此时使用ToDouble()