Reputation: 1
I have defined the following method which calculates the average of an array:
public int AverageOfArray (params int[] arr)
{
if (arr.Length > 0)
{
double avg = Sum(ints) / arr.Length;
return (int)avg;
}
return 0;
}
My requirement is that the average should be returned as an integer. When I tried to test this method using the int.MaxValue The unit test will fail. How can I make the test class pass?
UPDATED::-
public int Sum(params int[] arr)
{
int total = 0;
for (int n = 0; n < arr.Length; n++)
{
total += arr[n];
}
return total;
}
Upvotes: 0
Views: 172
Reputation: 55409
In the Sum
method, the int
data type is not sufficient to hold the sum of int.MaxValue / 2
and int.MaxValue / 2 + 4
:
int.MaxValue / 2 = 0x3FFFFFFF
int.MaxValue / 2 + 4 = 0x40000003
--------------------------------------
Sum: int.MaxValue - 1 + 4 = 0x80000002 (subtract 1 because int.MaxValue is odd)
Because the correct sum exceeds int.MaxValue
, it overflows into the sign bit, causing the result to be 232 less than the correct sum (see Two's complement on Wikipedia for more information):
Correct sum: 2147483650
Actual sum: -2147483646
The actual sum is wrong, so when you divide it by 2, you get the wrong average too. Garbage in, garbage out!
To fix this problem, change the return type of Sum
to long
, and change the type of the total
variable to long
as well:
public long Sum(params int[] arr)
{
long total = 0;
for (int n = 0; n < arr.Length; n++)
{
total += arr[n];
}
return total;
}
Now the Sum
method returns the correct sum: int.MaxValue + 3
is less than long.MaxValue
, so no overflow occurs.
Upvotes: 2
Reputation: 7282
This should work for you
public int AverageOfArray (params int[] arr)
{
double avg = 0;
if (arr.Length > 0)
{
for (int n = 0; n < arr.Length; n++)
{
avg += arr[n]/arr.Length;
}
}
return (int)avg;
}
Upvotes: 0