-2
ViewBag.WinLossRatio = 
    new WinLossRatioVM
    {
        Wins = ctx.Games.Where(p => p.IsWin == true).Count(),
        Total = ctx.Games.Count(),
        Percent = ctx.Games.Where(p => p.IsWin == true).Count() / ctx.Games.Count() * 100
    };

In the above code, I simply try to get the ratio of wins to the total number of games played. The first two properties, Wins and Total return five and eleven, respectively. The last property only returns as zero. The model is simply as follows:

public class WinLossRatioVM
{
    public int Wins { get; set; }
    public int Total { get; set; }
    public int Percent { get; set; }
}

Why does Percent return zero?

user1477388
  • 20,790
  • 32
  • 144
  • 264
  • 3
    there are at least thousands of questions about this. – Selman Genç May 23 '14 at 00:59
  • why are you defining `Wins` and `Total` when you are not using it? Shouldn't it be `Percent = Wins / Total * 100`? – Ben May 23 '14 at 00:59
  • @Ben, likely they are used somewhere else. That being said, the reuse makes sense to me. – BradleyDotNET May 23 '14 at 01:00
  • @Ben You can't use those since they haven't been defined yet. – user1477388 May 23 '14 at 01:00
  • other duplicates: 1) [Dividing by two integers does not return expected result](http://stackoverflow.com/questions/11487577/dividing-by-two-integers-does-not-return-expected-result) 2) [What's wrong with this division?](http://stackoverflow.com/questions/704702/whats-wrong-with-this-division) 3) [Divide not returning the decimal value I expect](http://stackoverflow.com/questions/2597029/divide-not-returning-the-decimal-value-i-expect) – Selman Genç May 23 '14 at 01:02
  • @Selman22 And how the hell was I supposed to find that; this would have been a difficult problem to google for since it's so vague... – user1477388 May 23 '14 at 01:03
  • 1
    By the way, replace `.Where(something).Count()` by `.Count(something)` directly. – Pierre-Luc Pineault May 23 '14 at 01:03
  • @user1477388 It ain't vague at all. Googling "C# Division returns 0" returns immediately [this answer](http://stackoverflow.com/questions/9288904/division-returns-zero), and [this one](http://stackoverflow.com/questions/1205490/why-do-these-division-equations-result-in-zero). And a bunch of [answers elsewhere](http://social.msdn.microsoft.com/Forums/vstudio/en-US/78281158-6479-49c9-b4ab-8c5bbcc250f1/why-does-this-seemlingly-sinple-division-always-return-0?forum=csharpgeneral) – Pierre-Luc Pineault May 23 '14 at 01:04
  • @Pierre-LucPineault I guess - just didn't think I would find anything for such a vague problem - it could be returning zero for a number of reasons it seemed. – user1477388 May 23 '14 at 01:05
  • @user1477388 There's over 645k questions in the C# tag alone, you can find almost anything if you search just a little bit. By the way I just saw there's 5 other questions exactly like yours in the section named "Linked"... – Pierre-Luc Pineault May 23 '14 at 01:09

2 Answers2

2

Cast the properties as decimals, float or double as you need the decimal places for the percentage calculation.

Xela
  • 2,322
  • 1
  • 17
  • 32
1
Percent = ctx.Games.Where(p => p.IsWin == true).Count() / ctx.Games.Count() * 100

Is using integer division, you need to cast at least one argument to a float so you are using floating point division:

Percent = Convert.ToInt32(ctx.Games.Where(p => p.IsWin == true).Count() / (float)(ctx.Games.Count()) * 100);

Integer division will truncate any fractional component, leaving 0 in percentage calculations < 100%

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • You can't do this, Wins and Total won't do not exist in that context, VS says. – user1477388 May 23 '14 at 01:01
  • I saw your comment below, you say it is common to cast to float instead of double; is there any advantage? – apxcode May 23 '14 at 01:02
  • @FunctionR, Not really. Float easily contains the range of an int, so you don't need the increased precision of double or decimal. Its also called "floating point division" so the use of float makes it obvious that thats what it will use. – BradleyDotNET May 23 '14 at 01:03
  • Another reason why this won't work, because you have to convert it to int, since Percent is int, `Percent = Convert.ToInt16(ctx.Picks.Where(p => p.IsWin == true).Count() / (float)ctx.Picks.Count() * 100)` – user1477388 May 23 '14 at 01:04
  • @user1477388, another excellent catch. Just cast the result to int (no need to use Convert if you don't want to) Edited to include the cast. The more common use of percent is as a float (so you get the precision), hence my lack of cast. – BradleyDotNET May 23 '14 at 01:05
  • Thanks, but the implicit cast won't work, it has to be done with the Convert method. – user1477388 May 23 '14 at 01:06
  • Whats the error you are getting? This seems to need some research, I swear I've done that before... Regardless, updated to your code in case I'm wrong :) – BradleyDotNET May 23 '14 at 01:08
  • Well I upvoted your post. The other folks aptly pointed out that this question has been answered time and time again - so i guess i will delete it. – user1477388 May 23 '14 at 01:11