如何在C#中将Decimal转换为Double?

问题描述 投票:0回答:13

我想将十进制变量

trans
分配给双精度变量
this.Opacity

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

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

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

c# floating-point type-conversion double decimal
13个回答
533
投票

像这样显式转换为

double
是没有必要的:

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

将常数识别为

5000.0
(或
5000d
)就足够了:

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

154
投票

通用问题“十进制与双精度?”的更通用答案:

Decimal 用于货币计算以保持精度。 Double 用于不受微小差异影响的科学计算。由于 Double 是 CPU 原生的类型(内部表示存储在 base 2 中),因此使用 Double 进行的计算比 Decimal 执行得更好(内部表示在 base 10 中)。


109
投票

您的代码在 VB.NET 中运行良好,因为它隐式执行任何强制转换,而 C# 既有隐式强制转换,也有显式强制转换。

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

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

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

(double)
必须在 C# 中明确声明,但可以通过 VB 更“宽容”的编译器来隐含


98
投票

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

78
投票

你有两个问题。

首先,

Opacity
需要一个双精度值,而不是十进制值。 编译器告诉您,虽然十进制和双精度之间存在转换,但这是一个显式转换,您需要指定它才能工作。

其次,

TrackBar.Value
是一个整数值,无论将 int 分配给什么类型的变量,将 int 除以 int 都会得到 int。在这种情况下,存在从 int 到decimal 或double 的隐式转换,因为进行转换时不会损失精度。所以编译器不会抱怨。但你得到的值大概总是 0,因为
trackBar.Value
总是小于 5000。

解决方案是更改代码以使用 double (不透明度的本机类型)并通过显式将常量设置为 double 来执行浮点算术,这将具有提升算术或将

trackBar.Value
转换为 double 的效果,这将做同样的事情或两者都做。除非在其他地方使用,否则不需要中间变量。我的猜测是编译器无论如何都会优化它。

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

72
投票

我认为,尽可能明确是可取的。这增加了代码的清晰度,并帮助最终可能阅读它的程序员同事。

除了(或代替)在号码后附加

.0
之外,您还可以使用
decimal.ToDouble()

以下是一些示例:

// Example 1
double transparency = trackBar1.Value/5000;
this.Opacity = decimal.ToDouble(transparency);

// Example 2 - with inline temp
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);

68
投票

听起来

this.Opacity
是一个双精度值,编译器不喜欢你试图在其中塞入十进制值。


63
投票

您应该使用

5000.0
而不是
5000


63
投票

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


58
投票

假设您使用的是 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
显式地将数字设为浮点值,编译器现在可以将其解释为双精度型并执行正确的计算。


52
投票

由于

Opacity
是一个双精度值,我从一开始就使用双精度值,根本不进行强制转换,但一定要在除法时使用双精度值,这样就不会丢失任何精度:

Opacity = trackBar1.Value / 5000.0;

51
投票

最好的解决办法是:

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

3
投票

OG 事实:

Double
类型代表比
Decimal
更广泛的可能值。

选角为替身

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

类型转换

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

没有明确的演员/转换

在这种情况下,在常量

5000d
末尾添加“d”或“.0”
5000.0
将标识所需的类型。当运算中没有常数时,只需将您的
decimal
变量乘以
1.0
1d
即可。

© www.soinside.com 2019 - 2024. All rights reserved.