Вычисление процентов в C#

Что мне здесь не хватает, пытаясь рассчитать процент завершения? Мое процентное уравнение, похоже, возвращает неверный процент.

Int32 counter = 0;

foreach (var vehicle in vehicles)
{
    counter += 1;

    Int32 percentage = (Int32)((double)counter * vehicles.Count()) / 100;

    _worker.ReportProgress(percentage);


    if (_worker.CancellationPending)
    {
        e.Cancel = true;
        _worker.ReportProgress(0);
        return;
    }
}

person Steven Rogers    schedule 19.10.2012    source источник
comment
Мое процентное уравнение, похоже, возвращает неверный процент. Какие входные значения дают какое выходное значение и чего вы ожидали? Можете ли вы переписать это как короткое, но полное консольное приложение? (Это должно быть тривиально.)   -  person Jon Skeet    schedule 19.10.2012
comment
Почему вы умножаете счетчик на счет, а не делите? Я думаю, что вы немного отстали в своей формуле там...   -  person iMortalitySX    schedule 19.10.2012
comment
iMortalitySX, вы правы. Я получил это немного назад. :)   -  person Steven Rogers    schedule 19.10.2012


Ответы (4)


Чтобы вычислить проценты, вы должны делать

progress
--------  x 100
 total

Ты делаешь

progress x total
----------------
       100

Попробуйте вместо этого использовать (counter * 100) / vehicles.Count().

Примечание. Если вы выполняете умножение на 100 перед делением, это означает, что вам не нужно возиться с приведением к числам с плавающей запятой/двойным числом, однако это означает, что все ваши проценты округляются в меньшую сторону. Если вам нужен более точный процент, используйте удвоение и не беспокойтесь о порядке.

person Justin    schedule 19.10.2012
comment
Да, до меня дошло, что это правильный маршрут. Я не спал прошлой ночью, я думаю. :) - person Steven Rogers; 19.10.2012
comment
Если у меня есть 1, 4, 1, и я пытаюсь получить процент, используя Math.Round(), я получаю 17%, 67%, 17%, что в сумме дает 101%. Как мне это исправить? - person Si8; 14.07.2016

как насчет

     Int32 percentage = counter * 100 / vehicles.Count();
person user287107    schedule 19.10.2012
comment
+1, но не забудьте проверить Count() != 0 (или транспортные средства != null, если уж на то пошло). - person iMortalitySX; 19.10.2012
comment
как и в цикле foreach, Count всегда › 0, если выполняется код внутри цикла - person user287107; 19.10.2012
comment
LOL, вы правы, я просто имел в виду, что в общем случае вы бы проверили это. - person iMortalitySX; 19.10.2012

Попробуй это :-

  int percentage= (int)( ((100f * counter) / vehicles.count()));

Приведите к типу с плавающей запятой, чтобы целочисленное деление не дало вам ноль, и вы можете добавить 0,5 для целочисленного округления. Используйте 0.5f, а не 0.5, чтобы он не расширялся до двойного, т.е.

  int percentage= (int)(0.5f + ((100f * counter) / vehicles.count()));
person Rahul Tripathi    schedule 19.10.2012

Вы также можете использовать Math.round():

Int32 percentage = (Int32)Math.Round( (double)(counter * 100) / vehicles.Count());
person Sogger    schedule 19.02.2014
comment
Если у меня есть 1, 4, 1, и я пытаюсь получить процент, используя Math.Round(), я получаю 17%, 67%, 17%, что в сумме дает 101%. Как мне это исправить? - person Si8; 14.07.2016
comment
Вы теряете информацию до того, как заработаете; вы должны быть более точными, прежде чем подводить итоги, иначе вы не можете ожидать, что ваши последующие вычисления сохранят значительную точность. например В вашем примере сохранение одного десятичного знака с помощью Math.Round(x,1) приведет к сумме 100,1, которая будет округлена до 100. - person Sogger; 15.07.2016