0

I am running a simple query and calculating the percentage of two values. Every time this run's the calculation returns zero. The calculation is cast to a decimal also, so I can't see what the problem is.

from e in db.hours
select new
{
    OverTimeHoursPercentage = (decimal)((1088 / 22000) * 100)
};

After the query is ran, I can see in the debugger, the type of OverTimeHoursPercentage is a decimal, and that the value calculated is zero when it should be 4.94.

Any ideas of whats going on?

Drag and Drop
  • 2,672
  • 3
  • 25
  • 37
SK2017
  • 753
  • 9
  • 38
  • `1088/ 22000` is not `decimal`, it's an `int` division. Add `M` to one of the constants to fix this problem, e.g. `1088M / 22000` – Sergey Kalinichenko May 22 '18 at 11:11
  • See [this Q&A](https://stackoverflow.com/a/36431095/335858) for a longer explanation. – Sergey Kalinichenko May 22 '18 at 11:15
  • @DragandDrop I remember answering a similar question in the past, so I quickly fetched a link to it. I didn't suggest closing this question as a duplicate of the linked Q&A, though, and I am sure that there are better duplicate targets for it. – Sergey Kalinichenko May 22 '18 at 11:47
  • @dasblinkenlight, Sorry, Just pointing out that answer here a a bit more explicative and even your comment is clearer that the linked one. It may have sound like i was talking about self promoting when I was in fact addressing the fact that it was not really a longer explation. – Drag and Drop May 22 '18 at 11:53

2 Answers2

1

1088 and 22000 are integers, and with integer math 1088 / 22000 is 0. 0 * 100 is also 0. And, when converted to a decimal, 0 is 0.0.

What you want to do is perform your conversion before performing the calculations. Fortunately you can do this directly in a literal value (at compile time) without having to cast (at run time). Appending M to any one value in the expression should do the trick:

(1088M / 22000) * 100

or you can explicitly mark them all as decimals:

(1088M / 22000M) * 100M

With this you can remove the cast, as the result of the decimal expression will itself be a decimal:

OverTimeHoursPercentage = (1088M / 22000M) * 100M
David
  • 208,112
  • 36
  • 198
  • 279
0

Dividing 2 integers will produce an integer result, which will lose any of the decimal precision you are looking for.

So you need to make at least one of the values in the division a decimal. Casting after the calculation is too late, the damage is already done.

Try this:

OverTimeHoursPercentage = (((decimal)1088 / 22000)*100)

or better still, if it is a literal value, then declare it as a decimal and don't cast (note the m):

OverTimeHoursPercentage = ((1088m / 22000)*100)
musefan
  • 47,875
  • 21
  • 135
  • 185