【问题标题】:Getting a value of 0 when dividing 2 longs in c#在 c# 中除以 2 个 long 时得到 0 的值
【发布时间】:2012-09-15 04:50:06
【问题描述】:

我正在尝试划分 DriveInfo.AvailableFreeSpace 和 DriveInfo.TotalSize 的值,以尝试获取其中的百分比以在进度条中使用。

我需要结束值是一个 int,因为 progressbar.value 需要一个 int 并且上述方法返回一个 long。

我有这个作为值:

164660715520---AvailableFreeSpace

256058060800---总尺寸

当我尝试使用此方法设置 progressbar.value 时,我也收到错误:

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

当我使用此代码尝试获取一个值时,它只返回一个 0。

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

我什至试过这个,但它不起作用:

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

我知道我仍然需要进行一些格式化才能让它看起来不错,但是每当我运行代码时它只会返回一个 0。

会不会跟long到int的转换有关?

【问题讨论】:

  • 164660715520/256058060800的值为0.64。这就是我想你得到 0 的原因。

标签: c# casting int long-integer


【解决方案1】:

整数除法只返回整数部分。所以 3/5 将是 0。您需要将至少一个因素视为浮点数。试试这个:

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

【讨论】:

  • 现在我可以把它转换成一个整数来得到一个整数吗?
  • @Sempus 如果你只想要整数部分,你可以先*100
  • 在某些情况下,double 不足以覆盖 long
  • 十进制大于long使用128位,double使用64位,与long相同
  • @Sempus:啊,我明白你的意思了。当然可以,只需将最终结果投射到int
【解决方案2】:

立即将dInfo.AvailableFreeSpace 转换为int 的第一种方法行不通,因为您尝试转换的数字164660715520 不适合32 位。您需要尽可能保持 64 位。

避免浮点运算的诀窍是先乘以100,然后再进行除法。

只要100 的次数在允许的大小范围内(在您的情况下是这样),结果就具有良好的精度:

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

【讨论】:

    【解决方案3】:

    该值向下舍入为 0,因为 long 类型不能有小数位,只能有整数。

    在乘以 100 之前转换为 decimal 类型

    例如(在我计算 ProgressBar 的进度百分比的情况下):

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

    代码如下:

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

    【讨论】:

      【解决方案4】:

      将 dInfo.AvailableFreeSpace 和 dInfo.TotalSize 设为十进制或双精度类型以避免强制转换 或者

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

      【讨论】:

        【解决方案5】:

        我可能有点晚了,但在尝试比较时间跨度时遇到了这个问题。最终我将每个 timepsan 转换为一个字符串并手动计算比率

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

        【讨论】:

          猜你喜欢
          • 2019-10-29
          • 1970-01-01
          • 2014-05-29
          • 1970-01-01
          • 1970-01-01
          • 2016-02-22
          • 2021-01-01
          • 2021-02-19
          • 2019-08-13
          相关资源
          最近更新 更多