16

I am trying to divide the values of DriveInfo.AvailableFreeSpace & DriveInfo.TotalSize to try and get a percentage of it to use in a progress bar.

I need the end value to be an int as progressbar.value requires an int and the above methods return a long.

I have this as the values:

164660715520---AvailableFreeSpace

256058060800---TotalSize

When I try and set the progressbar.value using this method I also get an error:

progressBar1.Value=(int)(dInfo.AvailableFreeSpace/dInfo.TotalSize)*100;

When I use this code to try and get a value it just returns a 0.

label10.Text =  (((int)dInfo.AvailableFreeSpace/dInfo.TotalSize)*100).ToString();

I've even tried this and it doesn't work:

label10.Text = ((dInfo.AvailableFreeSpace/dInfo.TotalSize)*100).ToString();

I know I still have to do some formatting to get it to look good but whenever I run the code it just returns a 0.

Could it have something to do with the conversion from long to int?

Zeratas
  • 1,005
  • 3
  • 17
  • 36

5 Answers5

27

Integer division returns only the integer part. So 3/5 will be 0. You'll need to treat at least one of the factors as a floating point number. Try this:

label10.Text =  (((int)((double)dInfo.AvailableFreeSpace/dInfo.TotalSize)*100)).ToString();
Tudor
  • 61,523
  • 12
  • 102
  • 142
16

The first way with casting dInfo.AvailableFreeSpace to int right away is not going to work, because the number 164660715520 that you are trying to cast does not fit in 32 bits. You need to stay in 64 bits as long as you can.

The trick to avoiding floating-point arithmetics is to multiply by 100 first, and then do the division.

As long as the number times 100 is within the allowed size (and in your case, it is) the result has a good precision:

label10.Text = ((100*dInfo.AvailableFreeSpace/dInfo.TotalSize)).ToString();

Demo on ideone (prints 64).

long total = 256058060800L;
long avail = 164660715520L;
var pct = (100*avail/total).ToString();
Console.WriteLine("{0}", pct); // 64
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
5

The value is rounding down to 0, as long types cannot have decimal places, only whole integers.

Cast as a decimal type before multiplying by 100

For Example (In my case where I am calculating progress percentage for ProgressBar):

double someVariable = (double)longVariable1 / (double)longVariable2;

Code is given below:

public partial class Form1 : Form
{
   public Form1()
    {
         web.ProgressChanged += new WebBrowserProgressChangedEventHandler(web_ProgressChanged);
    }

private void web_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
    {

        <strong>double t = (100 * (double)e.CurrentProgress / (double)e.MaximumProgress);</strong>
        if (t < 0)
            return;
        int c = (int)t;
        progressBar.Value = c;

        if (c == 100)
        {
            label1.Text = "Done";                
        }
    }
}
Curtis
  • 101,612
  • 66
  • 270
  • 352
1

make your dInfo.AvailableFreeSpace and dInfo.TotalSize decimal or double type to avoid casts Or

uselabel10.Text = (((double)dInfo.AvailableFreeSpace/dInfo.TotalSize)*100).ToString();

DSharper
  • 3,177
  • 9
  • 29
  • 47
0

I might be a bit late but I had this issue when trying to compare timespan's. Eventually I cast each timepsan to a string and manually computed the ratio

    private static double Improvement(string efficientTime, string inefficientTime)
    {
        var magnitude = Math.Pow(10, (inefficientTime.Length - efficientTime.Length));
        var time2 = (double) Convert.ToInt32(efficientTime.Substring(0, 5));
        var time1 = (double) Convert.ToInt32(inefficientTime.Substring(0, 5));
        var sigRatio = (time2 / time1);

        var sigPercent = sigRatio * magnitude;

        var improvement = sigPercent;
        return improvement;
    }
Zakk Diaz
  • 1,063
  • 10
  • 15