Multiply an integer against a fraction with rounding to whole number in C#

Viewed 792

I need to get two thirds and round to whole number.

Standard rounding:

  • .6 rounds to 1
  • .5 rounds to 1
  • .4 rounds to 0

AwayFromZero I believe is the right option to use here. But I think my multiplication is not right because I'm getting 0 for my result.

int totalPoints= 71625;
int twoThirds = (int)Math.Round((double)totalPoints * (2 / 3), 0, MidpointRounding.AwayFromZero);

Answer should be 47750.

3 Answers

Because 2/3 is an int calculation so it will return 0, then 0 * totalPoints equal 0

I would use 2/3m let the calculation result be decimal. then you can get your expectation result.

int totalPoints = 71625;
int twoThirds = (int)Math.Round(totalPoints * (2/3m), 0, MidpointRounding.AwayFromZero);

While the @D-Shih answer is correct here, it is not the best you can get. Even for decimal, two thirds are not representable exactly, 2/3m is not exactly two thirds, so rounding error occurs. When you multiply the number, you multiply the error too. It is better to make the dividing as last. Let me show the difference:

int totalPoints = 71625;
decimal result1 = totalPoints * (2 / 3m); //47750.000000000000000000000002M
decimal result2 = (decimal)totalPoints * 2 / 3; //47750 (exactly)
double result3 = (double)totalPoints * 2 / 3; //47750 (exactly)

not a big deal here, as the results would be the same. But if we alter the example a bit

double totalPointsDouble = 71626.5d;

decimal result1 = (decimal)totalPointsDouble * (1 / 3m); //23875.499999999999999999999998M
decimal result2 = (decimal)totalPointsDouble * 1 / 3m; //23875.5M
double result3 = totalPointsDouble * 1 / 3; //23875.5

int oneThird1 = (int)Math.Round((decimal)totalPointsDouble * (1 / 3m), 0, MidpointRounding.AwayFromZero);
//23875
int oneThird3 = (int)Math.Round(totalPointsDouble * 1 / 3, 0, MidpointRounding.AwayFromZero);
//23876

the rounding error propagates to the result and the results differ. According to math, 23876 is correct.

(2 / 3) is evaluated first because it is in parentheses. The result is 0 because this is an integer division.

Related