2016-08-19 2 views
0

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

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

ответ

1

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

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

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

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

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

Поведение в исходном коде образец называется целочисленным делением. См Division operator article in C# Specification или Why integer division in c# returns an integer but not a float? StackOverflow вопроса для получения дополнительной информации

+0

Так должно быть nr быть длинным и dr быть двойным или любым другим типом? – nikhil

+1

вы можете исправить это с помощью нескольких прикладов, '((double) nr/(double) dr)' – Cody

+1

На самом деле кастинг только одного достаточно, компилятор автоматически использует тип с максимальной точностью для операции. – Andrew

1

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

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

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

double value = nr * 100.0/dr; 
+1

Это то, что я сделал бы, он менее подробный и не менее эффективный. – Andrew

0

nr и dr оба являются long, которые по существу являются целыми числами. Если вы идете с (nr/dr), а 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; 
    } 
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); 
}