How to convert a Decimal to a Double in C#?

64,798

Solution 1

An explicit cast to double like this isn't necessary:

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

Identifying the constant as 5000.0 (or as 5000d) is sufficient:

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

Solution 2

A more generic answer for the generic question "Decimal vs Double?":

Decimal is for monetary calculations to preserve precision. Double is for scientific calculations that do not get affected by small differences. Since Double is a type that is native to the CPU (internal representation is stored in base 2), calculations made with Double perform better than Decimal (which is represented in base 10 internally).

Solution 3

Your code worked fine in VB.NET because it implicitly does any casts, while C# has both implicit and explicit ones.

In C# the conversion from decimal to double is explicit as you lose accuracy. For instance 1.1 can't be accurately expressed as a double, but can as a decimal (see "Floating point numbers - more inaccurate than you think" for the reason why).

In VB the conversion was added for you by the compiler:

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

That (double) has to be explicitly stated in C#, but can be implied by VB's more 'forgiving' compiler.

Solution 4

Why are you dividing by 5000? Just set the TrackBar's Minimum and Maximum values between 0 and 100 and then divide the Value by 100 for the Opacity percentage. The minimum 20 example below prevents the form from becoming completely invisible:

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;
}

Solution 5

You have two problems.

Firstly, Opacity requires a double, not a decimal value. The compiler is telling you that while there is a conversion between decimal and double, it is an explicit conversion that you need to specify in order for it to work.

Secondly, TrackBar.Value is an integer value and dividing an int by an int results in an int no matter what type of variable you assign it to. In this case there is an implicit cast from int to decimal or double, because there is no loss of precision when you do the cast. So the compiler doesn't complain. But the value you get is always 0, presumably, since trackBar.Value is always less than 5000.

The solution is to change your code to use double (the native type for Opacity) and do floating point arithmetic by explicitly making the constant a double, which will have the effect of promoting the arithmetic or casting trackBar.Value to double, which will do the same thing or both. You don't need the intermediate variable unless it is used elsewhere. My guess is the compiler would optimize it away anyway.

trackBar.Opacity = (double)trackBar.Value / 5000.0;
Share:
64,798
Eggs McLaren
Author by

Eggs McLaren

This is a puppet test account I use to validate "regular user" stuff on the site -- Jeff Atwood

Updated on July 24, 2022

Comments

  • Eggs McLaren
    Eggs McLaren almost 2 years

    I want to use a Track-Bar to change a Form's opacity.

    This is my code:

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

    When I build the application, it gives the following error:

    Cannot implicitly convert type decimal to double
    

    I have tried using trans and double, but then the Control doesn't work. This code worked fine in a past VB.NET project.

    • TraumaPony
      TraumaPony over 15 years
      Also, Decimal can't represent as wide a value as a Double. Decimal can only go up to +/-7.9228162514264337593543950335E+28; whereas a Double can go up to +/-1.79769313486232E+308
    • Franck
      Franck over 3 years
      @TraumaPony it's a trackbar. It is unlikely that it has ever been done to use such a high value on trackbar
    • JosephDoggie
      JosephDoggie about 3 years
      I was always told it is better to multiply by 0.0002 than divide by 5000.
    • Leo
      Leo about 2 years
      Fun Fact: This is the 4th question (The first still only visible) on stack overflow
  • jww
    jww over 9 years
    Wouldn't this just move the problem around? Rather than a problem with 5000, OP would have a problem with 100?