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