C# двойной тип данных дает 0 всегда

У меня есть следующая функция, которая обычно должна возвращать значение. Я вычисляю значение в приложении калькулятора и получаю значения просто отлично. Но в программе ниже значение переменной всегда равно 0. Я пытался использовать long, double, float, но ничего не работает. Пожалуйста помоги.

 public string CalculateElapsedPercent(DateTime endTime, DateTime startTime)
        {
            string result = string.Empty;
            DateTime currentTime = DateTime.Now;
            if (currentTime > endTime)
            {
                result = " (100 %)";
                return result;
            }
            long nr = (currentTime - startTime).Ticks;
            long dr = (endTime - startTime).Ticks;
            double value = (nr / dr) * 100.0;
            result = " (" + value.ToString() + " %)";
            return result;
        }

5 ответов

Решение

Поскольку оба nr а также dr являются long, результат (nr / dr) является long, и с тех пор dr больше, чем nr, результат равен 0,

Чтобы это исправить, вы можете преобразовать его в double при расчете:

double value = ((double)nr / (double)dr) * 100.0;

Или вы можете определить nr а также dr как double s:

double nr = (currentTime - startTime).Ticks;
double dr = (endTime - startTime).Ticks;
double value = (nr / dr) * 100.0;

Поведение в исходном образце кода называется целочисленным делением. См. Статью оператора деления в спецификации C# или Почему целочисленное деление в C# возвращает целое число, а не число с плавающей запятой? stackru вопрос для получения дополнительной информации

Вы выполняете целочисленное деление (nr / dr), что означает, что вы потеряете все десятичные значения.

Вместо этого вы хотите выполнить деление с плавающей запятой. Вы можете сделать это, применив nr или же dr в double, Или, в вашем случае, вы можете просто переместить умножение на 100.0 немного (умножение на 100.0, силы nr быть брошенным на doubleчто означает, что dr также будет автоматически приведен к double для деления):

double value = nr * 100.0 / dr;

nr а также dr являются целыми числами, что означает nr/dr является целочисленным делением, и так как dr всегда будет больше чем nr, вы получите ноль.

Преобразовать их в double до деления:

double nr = Convert.ToDouble((currentTime - startTime).Ticks);
double dr = Convert.ToDouble((endTime - startTime).Ticks);
double value = (nr / dr) * 100.0;

Другие уже объяснили проблему, но я также хотел бы предложить небольшое улучшение вашего метода. Например, вот так:

public static string CalculateElapsedPercent(DateTime endTime, DateTime startTime)
{
    double ratio;
    DateTime currentTime = DateTime.Now;
    if (currentTime > endTime)
    {
        ratio = 1;
    }
    else
    {
        var elapsed = currentTime - startTime;
        var total = endTime - startTime;
        ratio = elapsed.TotalMinutes / total.TotalMinutes;
    }
    return string.Format(" ({0:P2})", ratio);
}

Nr и Dr оба long который по существу целые числа. Если вы идете с (нр / др) и dr больше чем nrв результате деления вы бы получили ноль. Просто бросьте nr и dr, чтобы удвоить, и ваши проблемы будут решены.:)

    public string CalculateElapsedPercent(DateTime endTime, DateTime startTime)
    {
        string result = string.Empty;
        DateTime currentTime = DateTime.Now;
        if (currentTime > endTime)
        {
            result = " (100 %)";
            return result;
        }
        long nr = (currentTime - startTime).Ticks;
        long dr = (endTime - startTime).Ticks;
        double value = ((double)nr / (double)dr) * 100.0;
        result = " (" + value.ToString() + " %)";
        return result;
    }
Другие вопросы по тегам